expo-file-system 19.0.0-canary-20250404-3c3b5fd → 19.0.0-canary-20250811-5c940c0

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 (169) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/android/build.gradle +3 -2
  3. package/android/src/main/java/expo/modules/filesystem/FileSystemDirectory.kt +104 -0
  4. package/android/src/main/java/expo/modules/filesystem/FileSystemExceptions.kt +39 -32
  5. package/android/src/main/java/expo/modules/filesystem/{next/FileSystemFile.kt → FileSystemFile.kt} +65 -23
  6. package/android/src/main/java/expo/modules/filesystem/{next/FileSystemFileHandle.kt → FileSystemFileHandle.kt} +2 -2
  7. package/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt +156 -1005
  8. package/android/src/main/java/expo/modules/filesystem/FileSystemNextRecords.kt +45 -0
  9. package/android/src/main/java/expo/modules/filesystem/FileSystemPath.kt +163 -0
  10. package/android/src/main/java/expo/modules/filesystem/{AppDirectoriesModule.kt → legacy/AppDirectoriesModule.kt} +1 -1
  11. package/android/src/main/java/expo/modules/filesystem/{CountingRequestBody.kt → legacy/CountingRequestBody.kt} +1 -1
  12. package/android/src/main/java/expo/modules/filesystem/{FilePermissionModule.kt → legacy/FilePermissionModule.kt} +1 -1
  13. package/android/src/main/java/expo/modules/filesystem/legacy/FileSystemExceptions.kt +48 -0
  14. package/android/src/main/java/expo/modules/filesystem/{FileSystemFileProvider.kt → legacy/FileSystemFileProvider.kt} +1 -1
  15. package/android/src/main/java/expo/modules/filesystem/legacy/FileSystemLegacyModule.kt +1127 -0
  16. package/android/src/main/java/expo/modules/filesystem/{FileSystemPackage.kt → legacy/FileSystemPackage.kt} +1 -1
  17. package/android/src/main/java/expo/modules/filesystem/{FileSystemRecords.kt → legacy/FileSystemRecords.kt} +4 -6
  18. package/android/src/main/java/expo/modules/filesystem/unifiedfile/JavaFile.kt +65 -0
  19. package/android/src/main/java/expo/modules/filesystem/unifiedfile/SAFDocumentFile.kt +79 -0
  20. package/android/src/main/java/expo/modules/filesystem/unifiedfile/UnifiedFileInterface.kt +23 -0
  21. package/build/ExpoFileSystem.d.ts +12 -0
  22. package/build/ExpoFileSystem.d.ts.map +1 -0
  23. package/build/ExpoFileSystem.types.d.ts +288 -0
  24. package/build/ExpoFileSystem.types.d.ts.map +1 -0
  25. package/build/FileSystem.d.ts +58 -341
  26. package/build/FileSystem.d.ts.map +1 -1
  27. package/build/index.d.ts +1 -1
  28. package/build/index.d.ts.map +1 -1
  29. package/build/legacy/ExponentFileSystem.d.ts.map +1 -0
  30. package/build/legacy/ExponentFileSystem.web.d.ts.map +1 -0
  31. package/build/legacy/ExponentFileSystemShim.d.ts.map +1 -0
  32. package/build/legacy/FileSystem.d.ts +365 -0
  33. package/build/legacy/FileSystem.d.ts.map +1 -0
  34. package/build/{FileSystem.types.d.ts → legacy/FileSystem.types.d.ts} +2 -7
  35. package/build/legacy/FileSystem.types.d.ts.map +1 -0
  36. package/build/legacy/index.d.ts +3 -0
  37. package/build/legacy/index.d.ts.map +1 -0
  38. package/build/{types.d.ts → legacy/types.d.ts} +2 -2
  39. package/build/legacy/types.d.ts.map +1 -0
  40. package/build/pathUtilities/index.d.ts.map +1 -0
  41. package/build/pathUtilities/path.d.ts.map +1 -0
  42. package/build/pathUtilities/url.d.ts +4 -0
  43. package/build/pathUtilities/url.d.ts.map +1 -0
  44. package/build/streams.d.ts.map +1 -0
  45. package/expo-module.config.json +9 -3
  46. package/ios/ExpoFileSystem.podspec +1 -7
  47. package/ios/{Next/FileSystemDirectory.swift → FileSystemDirectory.swift} +44 -5
  48. package/ios/FileSystemExceptions.swift +23 -54
  49. package/ios/{Next/FileSystemFile.swift → FileSystemFile.swift} +38 -21
  50. package/ios/FileSystemModule.swift +232 -217
  51. package/ios/{Next/FileSystemPath.swift → FileSystemPath.swift} +34 -0
  52. package/ios/FileSystemRecords.swift +20 -59
  53. package/ios/{EXFileSystemLocalFileHandler.m → Legacy/EXFileSystemLocalFileHandler.m} +1 -1
  54. package/ios/Legacy/FileSystemLegacyExceptions.swift +99 -0
  55. package/ios/Legacy/FileSystemLegacyModule.swift +286 -0
  56. package/ios/Legacy/FileSystemLegacyRecords.swift +73 -0
  57. package/legacy.ts +1 -0
  58. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0-sources.jar +0 -0
  59. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0-sources.jar.md5 +1 -0
  60. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0-sources.jar.sha1 +1 -0
  61. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0-sources.jar.sha256 +1 -0
  62. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0-sources.jar.sha512 +1 -0
  63. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.aar +0 -0
  64. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.aar.md5 +1 -0
  65. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.aar.sha1 +1 -0
  66. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.aar.sha256 +1 -0
  67. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.aar.sha512 +1 -0
  68. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.module +187 -0
  69. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.module.md5 +1 -0
  70. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.module.sha1 +1 -0
  71. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.module.sha256 +1 -0
  72. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.module.sha512 +1 -0
  73. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.pom +77 -0
  74. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.pom.md5 +1 -0
  75. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.pom.sha1 +1 -0
  76. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.pom.sha256 +1 -0
  77. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.0.0-canary-20250811-5c940c0/expo.modules.filesystem-19.0.0-canary-20250811-5c940c0.pom.sha512 +1 -0
  78. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml +13 -0
  79. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.md5 +1 -0
  80. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha1 +1 -0
  81. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha256 +1 -0
  82. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha512 +1 -0
  83. package/mocks/ExponentFileSystem.ts +86 -0
  84. package/mocks/FileSystem.ts +52 -0
  85. package/package.json +4 -7
  86. package/src/ExpoFileSystem.ts +17 -0
  87. package/src/{next/ExpoFileSystem.types.ts → ExpoFileSystem.types.ts} +157 -21
  88. package/src/FileSystem.ts +118 -704
  89. package/src/index.ts +9 -1
  90. package/src/legacy/FileSystem.ts +760 -0
  91. package/src/{FileSystem.types.ts → legacy/FileSystem.types.ts} +2 -7
  92. package/src/legacy/index.ts +2 -0
  93. package/src/{types.ts → legacy/types.ts} +2 -2
  94. package/src/{next/pathUtilities → pathUtilities}/index.ts +29 -21
  95. package/src/{next/pathUtilities → pathUtilities}/path.ts +3 -3
  96. package/src/{next/pathUtilities → pathUtilities}/url.ts +19 -32
  97. package/src/{next/streams.ts → streams.ts} +1 -1
  98. package/android/src/main/java/expo/modules/filesystem/next/FileSystemDirectory.kt +0 -56
  99. package/android/src/main/java/expo/modules/filesystem/next/FileSystemNextExceptions.kt +0 -50
  100. package/android/src/main/java/expo/modules/filesystem/next/FileSystemNextModule.kt +0 -212
  101. package/android/src/main/java/expo/modules/filesystem/next/FileSystemNextRecords.kt +0 -11
  102. package/android/src/main/java/expo/modules/filesystem/next/FileSystemPath.kt +0 -105
  103. package/build/ExponentFileSystem.d.ts.map +0 -1
  104. package/build/ExponentFileSystem.web.d.ts.map +0 -1
  105. package/build/ExponentFileSystemShim.d.ts.map +0 -1
  106. package/build/FileSystem.types.d.ts.map +0 -1
  107. package/build/next/ExpoFileSystem.d.ts +0 -10
  108. package/build/next/ExpoFileSystem.d.ts.map +0 -1
  109. package/build/next/ExpoFileSystem.types.d.ts +0 -172
  110. package/build/next/ExpoFileSystem.types.d.ts.map +0 -1
  111. package/build/next/ExpoGoFileSystemNextStub.d.ts +0 -11
  112. package/build/next/ExpoGoFileSystemNextStub.d.ts.map +0 -1
  113. package/build/next/FileSystem.d.ts +0 -79
  114. package/build/next/FileSystem.d.ts.map +0 -1
  115. package/build/next/index.d.ts +0 -2
  116. package/build/next/index.d.ts.map +0 -1
  117. package/build/next/pathUtilities/index.d.ts.map +0 -1
  118. package/build/next/pathUtilities/path.d.ts.map +0 -1
  119. package/build/next/pathUtilities/url.d.ts +0 -5
  120. package/build/next/pathUtilities/url.d.ts.map +0 -1
  121. package/build/next/streams.d.ts.map +0 -1
  122. package/build/types.d.ts.map +0 -1
  123. package/ios/Next/FileSystemNextExceptions.swift +0 -56
  124. package/ios/Next/FileSystemNextModule.swift +0 -207
  125. package/ios/Next/FileSystemNextRecords.swift +0 -8
  126. package/ios/Tests/EXFileSystemSpec.swift +0 -55
  127. package/next.ts +0 -1
  128. package/src/next/ExpoFileSystem.ts +0 -15
  129. package/src/next/ExpoGoFileSystemNextStub.ts +0 -22
  130. package/src/next/FileSystem.ts +0 -175
  131. package/src/next/index.ts +0 -1
  132. /package/android/src/main/{AndroidManifest.xml → java/expo/modules/filesystem/AndroidManifest.xml} +0 -0
  133. /package/build/{ExponentFileSystem.d.ts → legacy/ExponentFileSystem.d.ts} +0 -0
  134. /package/build/{ExponentFileSystem.web.d.ts → legacy/ExponentFileSystem.web.d.ts} +0 -0
  135. /package/build/{ExponentFileSystemShim.d.ts → legacy/ExponentFileSystemShim.d.ts} +0 -0
  136. /package/build/{next/pathUtilities → pathUtilities}/index.d.ts +0 -0
  137. /package/build/{next/pathUtilities → pathUtilities}/path.d.ts +0 -0
  138. /package/build/{next/streams.d.ts → streams.d.ts} +0 -0
  139. /package/ios/{Next/FileSystemFileHandle.swift → FileSystemFileHandle.swift} +0 -0
  140. /package/ios/{EXFileSystemAssetLibraryHandler.h → Legacy/EXFileSystemAssetLibraryHandler.h} +0 -0
  141. /package/ios/{EXFileSystemAssetLibraryHandler.m → Legacy/EXFileSystemAssetLibraryHandler.m} +0 -0
  142. /package/ios/{EXFileSystemHandler.h → Legacy/EXFileSystemHandler.h} +0 -0
  143. /package/ios/{EXFileSystemLocalFileHandler.h → Legacy/EXFileSystemLocalFileHandler.h} +0 -0
  144. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionCancelableUploadTaskDelegate.h +0 -0
  145. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionCancelableUploadTaskDelegate.m +0 -0
  146. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionDownloadTaskDelegate.h +0 -0
  147. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionDownloadTaskDelegate.m +0 -0
  148. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionHandler.h +0 -0
  149. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionHandler.m +0 -0
  150. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionResumableDownloadTaskDelegate.h +0 -0
  151. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionResumableDownloadTaskDelegate.m +0 -0
  152. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionTaskDelegate.h +0 -0
  153. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionTaskDelegate.m +0 -0
  154. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionTaskDispatcher.h +0 -0
  155. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionTaskDispatcher.m +0 -0
  156. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionUploadTaskDelegate.h +0 -0
  157. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXSessionUploadTaskDelegate.m +0 -0
  158. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXTaskHandlersManager.h +0 -0
  159. /package/ios/{EXSessionTasks → Legacy/EXSessionTasks}/EXTaskHandlersManager.m +0 -0
  160. /package/ios/{Encoding.swift → Legacy/Encoding.swift} +0 -0
  161. /package/ios/{ExpoFileSystem.h → Legacy/ExpoFileSystem.h} +0 -0
  162. /package/ios/{FileSystemBackgroundSessionHandler.swift → Legacy/FileSystemBackgroundSessionHandler.swift} +0 -0
  163. /package/ios/{FileSystemHelpers.swift → Legacy/FileSystemHelpers.swift} +0 -0
  164. /package/ios/{NSData+EXFileSystem.h → Legacy/NSData+EXFileSystem.h} +0 -0
  165. /package/ios/{NSData+EXFileSystem.m → Legacy/NSData+EXFileSystem.m} +0 -0
  166. /package/ios/{NetworkingHelpers.swift → Legacy/NetworkingHelpers.swift} +0 -0
  167. /package/src/{ExponentFileSystem.ts → legacy/ExponentFileSystem.ts} +0 -0
  168. /package/src/{ExponentFileSystem.web.ts → legacy/ExponentFileSystem.web.ts} +0 -0
  169. /package/src/{ExponentFileSystemShim.ts → legacy/ExponentFileSystemShim.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,81 @@
4
4
 
5
5
  ### 🛠 Breaking changes
6
6
 
7
+ - Make the modern filesystem API the default, move previous one to `expo-file-system/legacy`. ([#38404](https://github.com/expo/expo/pull/38404) by [@aleqsio](https://github.com/aleqsio))
8
+
9
+ ### 🎉 New features
10
+
11
+ - Make file implement blob interface directly. ([#38160](https://github.com/expo/expo/pull/38160) by [@aleqsio](https://github.com/aleqsio))
12
+ - Add directory info function ([#37910](https://github.com/expo/expo/pull/37910) by [@Wenszel](https://github.com/Wenszel))
13
+ - Add total and available sizes, directory sizes. ([#37594](https://github.com/expo/expo/pull/37594) by [@aleqsio](https://github.com/aleqsio))
14
+ - 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))
15
+ - Add support for custom headers in downloadFileAsync ([#36108](https://github.com/expo/expo/pull/36108) by [@leonhh](https://github.com/leonhh))
16
+ - [next] Add limited support for SAF Uris. ([#38075](https://github.com/expo/expo/pull/38075) by [@aleqsio](https://github.com/aleqsio))
17
+ - [next] Add full support for SAF Uris. ([#38075](https://github.com/expo/expo/pull/38075) by [@aleqsio](https://github.com/aleqsio))
18
+
19
+ ### 🐛 Bug fixes
20
+
21
+ - Update exists logic to align with documentation ([#37692](https://github.com/expo/expo/pull/37692) by [@Wenszel](https://github.com/Wenszel))
22
+ - Fix memory usage issue in getInfoAsync ([#37417](https://github.com/expo/expo/pull/37417) by [@Wenszel](https://github.com/Wenszel))
23
+ - Improved type safety in the FileSystem module to support tsconfig setups with stricter rules than the default. ([#37107](https://github.com/expo/expo/pull/37107) by [@hirbod](https://github.com/hirbod))
24
+ - Added required modifiers in the FileSystem module to support tsconfig setups with stricter rules than the default. ([#37467](https://github.com/expo/expo/pull/37467)
25
+
26
+ ### 💡 Others
27
+
28
+ ## 18.1.11 - 2025-07-01
29
+
30
+ ### 💡 Others
31
+
32
+ - Remove "Please" from warnings and errors ([#36862](https://github.com/expo/expo/pull/36862) by [@brentvatne](https://github.com/brentvatne))
33
+
34
+ ## 18.1.10 — 2025-05-08
35
+
36
+ ### 🐛 Bug fixes
37
+
38
+ - Fix the `UploadTask.uploadAsync` method's return type did not indicate that the method could resolve to `null`. ([#36476](https://github.com/expo/expo/pull/36476) by [@DoctorJohn](https://github.com/DoctorJohn))
39
+
40
+ ## 18.1.9 — 2025-05-03
41
+
42
+ _This version does not introduce any user-facing changes._
43
+
44
+ ## 18.1.8 — 2025-04-30
45
+
46
+ _This version does not introduce any user-facing changes._
47
+
48
+ ## 18.1.7 — 2025-04-28
49
+
50
+ ### 💡 Others
51
+
52
+ - Remove `web-streams-polyfill` in favor of `expo` support. ([#36407](https://github.com/expo/expo/pull/36407) by [@EvanBacon](https://github.com/EvanBacon))
53
+
54
+ ## 18.1.6 — 2025-04-25
55
+
56
+ _This version does not introduce any user-facing changes._
57
+
58
+ ## 18.1.5 — 2025-04-21
59
+
60
+ _This version does not introduce any user-facing changes._
61
+
62
+ ## 18.1.4 — 2025-04-14
63
+
64
+ _This version does not introduce any user-facing changes._
65
+
66
+ ## 18.1.3 — 2025-04-11
67
+
68
+ _This version does not introduce any user-facing changes._
69
+
70
+ ## 18.1.2 — 2025-04-11
71
+
72
+ _This version does not introduce any user-facing changes._
73
+
74
+ ## 18.1.1 — 2025-04-09
75
+
76
+ _This version does not introduce any user-facing changes._
77
+
78
+ ## 18.1.0 — 2025-04-04
79
+
80
+ ### 🛠 Breaking changes
81
+
7
82
  - Bump minimum macOS version to 11.0. ([#34980](https://github.com/expo/expo/pull/34980) by [@gabrieldonadel](https://github.com/gabrieldonadel))
8
83
 
9
84
  ### 🎉 New features
@@ -12,6 +87,7 @@
12
87
 
13
88
  ### 🐛 Bug fixes
14
89
 
90
+ - [next] Fix inconsistent behavior when using special chars in filenames. ([#35801](https://github.com/expo/expo/pull/35801) by [@aleqsio](https://github.com/aleqsio))
15
91
  - Fix expo-updates breaking filesystem on Android API 24 and 25. ([#33694](https://github.com/expo/expo/pull/33694) by [@aleqsio](https://github.com/aleqsio))
16
92
 
17
93
  ### 💡 Others
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '18.0.4'
7
+ version = '19.0.0-canary-20250811-5c940c0'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.filesystem"
11
11
  defaultConfig {
12
12
  versionCode 30
13
- versionName "18.0.4"
13
+ versionName "19.0.0-canary-20250811-5c940c0"
14
14
  }
15
15
  }
16
16
 
@@ -21,4 +21,5 @@ dependencies {
21
21
  api 'com.squareup.okhttp3:okhttp-urlconnection:4.9.2'
22
22
  api 'com.squareup.okio:okio:2.9.0'
23
23
  api "androidx.legacy:legacy-support-v4:1.0.0"
24
+ api "androidx.documentfile:documentfile:1.1.0"
24
25
  }
@@ -0,0 +1,104 @@
1
+ package expo.modules.filesystem
2
+
3
+ import android.net.Uri
4
+ import expo.modules.interfaces.filesystem.Permission
5
+
6
+ class FileSystemDirectory(uri: Uri) : FileSystemPath(uri) {
7
+ fun validatePath() {
8
+ // Kept empty for now, but can be used to validate if the path is a valid directory path.
9
+ }
10
+
11
+ override fun validateType() {
12
+ if (file.exists() && !file.isDirectory()) {
13
+ throw InvalidTypeFolderException()
14
+ }
15
+ }
16
+
17
+ val exists: Boolean get() {
18
+ return if (checkPermission(Permission.READ)) {
19
+ file.isDirectory()
20
+ } else {
21
+ false
22
+ }
23
+ }
24
+
25
+ val size: Long get() {
26
+ validatePermission(Permission.READ)
27
+ validateType()
28
+ return file.walkTopDown().filter { it.isFile() }.map { it.length() }.sum()
29
+ }
30
+
31
+ fun info(): DirectoryInfo {
32
+ validateType()
33
+ validatePermission(Permission.READ)
34
+ if (!file.exists()) {
35
+ val directoryInfo = DirectoryInfo(
36
+ exists = false,
37
+ uri = slashifyFilePath(file.uri.toString())
38
+ )
39
+ return directoryInfo
40
+ }
41
+
42
+ val directoryInfo = DirectoryInfo(
43
+ exists = true,
44
+ uri = slashifyFilePath(file.uri.toString()),
45
+ files = file.listFilesAsUnified().mapNotNull { i -> i.fileName },
46
+ modificationTime = modificationTime,
47
+ creationTime = creationTime,
48
+ size = size
49
+ )
50
+ return directoryInfo
51
+ }
52
+
53
+ fun create(options: CreateOptions = CreateOptions()) {
54
+ validateType()
55
+ validatePermission(Permission.WRITE)
56
+ validateCanCreate(options)
57
+ if (uri.isContentUri) {
58
+ throw UnableToCreateException("create function does not work with SAF Uris, use `createDirectory` and `createFile` instead")
59
+ }
60
+ if (options.overwrite && file.exists()) {
61
+ file.delete()
62
+ }
63
+ val created = if (options.intermediates) {
64
+ javaFile.mkdirs()
65
+ } else {
66
+ javaFile.mkdir()
67
+ }
68
+ if (!created) {
69
+ throw UnableToCreateException("directory already exists or could not be created")
70
+ }
71
+ }
72
+
73
+ fun createFile(mimeType: String?, fileName: String): FileSystemFile {
74
+ validateType()
75
+ validatePermission(Permission.WRITE)
76
+ val newFile = file.createFile(mimeType ?: "text/plain", fileName) ?: throw UnableToCreateException("file could not be created")
77
+ return FileSystemFile(newFile.uri)
78
+ }
79
+
80
+ fun createDirectory(fileName: String): FileSystemDirectory {
81
+ validateType()
82
+ validatePermission(Permission.WRITE)
83
+ val newDirectory = file.createDirectory(fileName) ?: throw UnableToCreateException("directory could not be created")
84
+ return FileSystemDirectory(newDirectory.uri)
85
+ }
86
+
87
+ // this function is internal and will be removed in the future (when returning arrays of shared objects is supported)
88
+ fun listAsRecords(): List<Map<String, Any>> {
89
+ validateType()
90
+ validatePermission(Permission.READ)
91
+ return file.listFilesAsUnified().map {
92
+ val uriString = it.uri.toString()
93
+ mapOf(
94
+ "isDirectory" to it.isDirectory(),
95
+ "uri" to if (uriString.endsWith("/")) uriString else "$uriString/"
96
+ )
97
+ }
98
+ }
99
+
100
+ fun asString(): String {
101
+ val uriString = file.uri.toString()
102
+ return if (uriString.endsWith("/")) uriString else "$uriString/"
103
+ }
104
+ }
@@ -1,48 +1,55 @@
1
1
  package expo.modules.filesystem
2
-
3
- import android.net.Uri
2
+ import expo.modules.interfaces.filesystem.Permission
4
3
  import expo.modules.kotlin.exception.CodedException
5
4
 
6
- internal class FileSystemOkHttpNullException :
7
- CodedException("okHttpClient is null")
5
+ internal class CopyOrMoveDirectoryToFileException :
6
+ CodedException("Unable to copy or move a folder to a file")
8
7
 
9
- internal class FileSystemCannotReadDirectoryException(uri: Uri?) :
10
- CodedException("Uri '$uri' doesn't exist or isn't a directory")
8
+ internal class InvalidTypeFolderException :
9
+ CodedException("A file with the same name already exists in the folder location")
11
10
 
12
- internal class FileSystemCannotCreateDirectoryException(uri: Uri?) :
13
- CodedException(
14
- uri?.let {
15
- "Directory '$it' could not be created or already exists"
16
- } ?: "Unknown error"
17
- )
11
+ internal class InvalidTypeFileException :
12
+ CodedException("A folder with the same name already exists in the file location")
18
13
 
19
- internal class FileSystemUnreadableDirectoryException(uri: String) :
20
- CodedException("No readable files with the uri '$uri'. Please use other uri")
14
+ internal class DestinationDoesNotExistException :
15
+ CodedException("The destination path does not exist")
21
16
 
22
- internal class FileSystemCannotCreateFileException(uri: Uri?) :
17
+ internal class UnableToDownloadException(reason: String) :
23
18
  CodedException(
24
- uri?.let {
25
- "Provided uri '$it' is not pointing to a directory"
26
- } ?: "Unknown error"
19
+ "Unable to download a file: $reason"
27
20
  )
28
21
 
29
- internal class FileSystemFileNotFoundException(uri: Uri?) :
30
- CodedException("File '$uri' could not be deleted because it could not be found")
22
+ internal class UnableToDeleteException(reason: String) :
23
+ CodedException(
24
+ "Unable to delete file or directory: $reason"
25
+ )
31
26
 
32
- internal class FileSystemPendingPermissionsRequestException :
33
- CodedException("You have an unfinished permission request")
27
+ internal class UnableToCreateException(reason: String) :
28
+ CodedException(
29
+ "Unable to create file or directory: $reason"
30
+ )
34
31
 
35
- internal class FileSystemCannotMoveFileException(fromUri: Uri, toUri: Uri) :
36
- CodedException("File '$fromUri' could not be moved to '$toUri'")
32
+ internal class InvalidPermissionException(permission: Permission) :
33
+ CodedException(
34
+ "Missing '${permission.name}' permission for accessing the file."
35
+ )
37
36
 
38
- internal class FileSystemUnsupportedSchemeException :
39
- CodedException("Can't read Storage Access Framework directory, use StorageAccessFramework.readDirectoryAsync() instead")
37
+ internal class UnableToReadHandleException(reason: String) :
38
+ CodedException(
39
+ "Unable to read from a file handle: '$reason'"
40
+ )
40
41
 
41
- internal class FileSystemCannotFindTaskException :
42
- CodedException("Cannot find task")
42
+ internal class UnableToWriteHandleException(reason: String) :
43
+ CodedException(
44
+ "Unable to write to a file handle: '$reason'"
45
+ )
43
46
 
44
- internal class FileSystemCopyFailedException(uri: Uri?) :
45
- CodedException("File '$uri' could not be copied because it could not be found")
47
+ internal class UnableToGetInfoException(reason: String) :
48
+ CodedException(
49
+ "Unable to get info from a file: '$reason'"
50
+ )
46
51
 
47
- internal class CookieHandlerNotFoundException :
48
- CodedException("Failed to find CookieHandler")
52
+ internal class DestinationAlreadyExistsException :
53
+ CodedException(
54
+ "Destination already exists"
55
+ )
@@ -1,17 +1,15 @@
1
- package expo.modules.filesystem.next
1
+ package expo.modules.filesystem
2
2
 
3
3
  import android.net.Uri
4
4
  import android.util.Base64
5
- import android.webkit.MimeTypeMap
6
5
  import expo.modules.interfaces.filesystem.Permission
7
6
  import expo.modules.kotlin.apifeatures.EitherType
8
7
  import expo.modules.kotlin.typedarray.TypedArray
9
- import java.io.File
10
8
  import java.io.FileOutputStream
11
9
  import java.security.MessageDigest
12
10
 
13
11
  @OptIn(EitherType::class)
14
- class FileSystemFile(file: File) : FileSystemPath(file) {
12
+ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
15
13
  // Kept empty for now, but can be used to validate if the uri is a valid file uri. // TODO: Move to the constructor once also moved on iOS
16
14
  fun validatePath() {
17
15
  }
@@ -20,27 +18,33 @@ class FileSystemFile(file: File) : FileSystemPath(file) {
20
18
  // After calling this function, we can use the `isDirectory` and `isFile` functions safely as they will match the shared class used.
21
19
  override fun validateType() {
22
20
  validatePermission(Permission.READ)
23
- if (file.exists() && file.isDirectory) {
21
+ if (file.exists() && file.isDirectory()) {
24
22
  throw InvalidTypeFileException()
25
23
  }
26
24
  }
27
25
 
28
26
  val exists: Boolean get() {
29
- validatePermission(Permission.READ)
30
- return file.isFile
27
+ return if (checkPermission(Permission.READ)) {
28
+ file.isFile()
29
+ } else {
30
+ false
31
+ }
31
32
  }
32
33
 
33
34
  fun create(options: CreateOptions = CreateOptions()) {
34
35
  validateType()
35
36
  validatePermission(Permission.WRITE)
36
37
  validateCanCreate(options)
37
- if (options.overwrite && file.exists()) {
38
- file.delete()
38
+ if (uri.isContentUri) {
39
+ throw UnableToCreateException("create function does not work with SAF Uris, use `createDirectory` and `createFile` instead")
40
+ }
41
+ if (options.overwrite && exists) {
42
+ javaFile.delete()
39
43
  }
40
44
  if (options.intermediates) {
41
- file.parentFile?.mkdirs()
45
+ javaFile.parentFile?.mkdirs()
42
46
  }
43
- val created = file.createNewFile()
47
+ val created = javaFile.createNewFile()
44
48
  if (!created) {
45
49
  throw UnableToCreateException("file already exists or could not be created")
46
50
  }
@@ -52,8 +56,8 @@ class FileSystemFile(file: File) : FileSystemPath(file) {
52
56
  if (!exists) {
53
57
  create()
54
58
  }
55
- FileOutputStream(file).use {
56
- it.write(content.toByteArray())
59
+ file.outputStream().use { outputStream ->
60
+ outputStream.write(content.toByteArray())
57
61
  }
58
62
  }
59
63
 
@@ -63,40 +67,56 @@ class FileSystemFile(file: File) : FileSystemPath(file) {
63
67
  if (!exists) {
64
68
  create()
65
69
  }
66
- FileOutputStream(file).use {
67
- it.channel.write(content.toDirectBuffer())
70
+ if (uri.isContentUri) {
71
+ file.outputStream().use { outputStream ->
72
+ val array = ByteArray(content.length)
73
+ content.toDirectBuffer().get(array)
74
+ outputStream.write(array)
75
+ }
76
+ } else {
77
+ FileOutputStream(javaFile).use {
78
+ it.channel.write(content.toDirectBuffer())
79
+ }
68
80
  }
69
81
  }
70
82
 
71
83
  fun asString(): String {
72
- val uriString = Uri.fromFile(file).toString()
84
+ val uriString = file.uri.toString()
73
85
  return if (uriString.endsWith("/")) uriString.dropLast(1) else uriString
74
86
  }
75
87
 
76
88
  fun text(): String {
77
89
  validateType()
78
90
  validatePermission(Permission.READ)
79
- return file.readText()
91
+ return file.inputStream().use { inputStream ->
92
+ inputStream.bufferedReader().use { it.readText() }
93
+ }
80
94
  }
81
95
 
82
96
  fun base64(): String {
83
97
  validateType()
84
98
  validatePermission(Permission.READ)
85
- return Base64.encodeToString(file.readBytes(), Base64.NO_WRAP)
99
+ file.inputStream().use {
100
+ return Base64.encodeToString(it.readBytes(), Base64.NO_WRAP)
101
+ }
86
102
  }
87
103
 
88
104
  fun bytes(): ByteArray {
89
105
  validateType()
90
106
  validatePermission(Permission.READ)
91
- return file.readBytes()
107
+ file.inputStream().use {
108
+ return it.readBytes()
109
+ }
92
110
  }
93
111
 
94
112
  @OptIn(ExperimentalStdlibApi::class)
95
113
  val md5: String get() {
96
114
  validatePermission(Permission.READ)
97
115
  val md = MessageDigest.getInstance("MD5")
98
- val digest = md.digest(file.readBytes())
99
- return digest.toHexString()
116
+ file.inputStream().use {
117
+ val digest = md.digest(it.readBytes())
118
+ return digest.toHexString()
119
+ }
100
120
  }
101
121
 
102
122
  val size: Long? get() {
@@ -108,7 +128,29 @@ class FileSystemFile(file: File) : FileSystemPath(file) {
108
128
  }
109
129
 
110
130
  val type: String? get() {
111
- return MimeTypeMap.getFileExtensionFromUrl(file.path)
112
- ?.run { MimeTypeMap.getSingleton().getMimeTypeFromExtension(lowercase()) }
131
+ return file.type
132
+ }
133
+
134
+ fun info(options: InfoOptions?): FileInfo {
135
+ validateType()
136
+ validatePermission(Permission.READ)
137
+ if (!file.exists()) {
138
+ val fileInfo = FileInfo(
139
+ exists = false,
140
+ uri = slashifyFilePath(file.uri.toString())
141
+ )
142
+ return fileInfo
143
+ }
144
+ val fileInfo = FileInfo(
145
+ exists = true,
146
+ uri = slashifyFilePath(file.uri.toString()),
147
+ size = size,
148
+ modificationTime = modificationTime,
149
+ creationTime = creationTime
150
+ )
151
+ if (options != null && options.md5 == true) {
152
+ fileInfo.md5 = md5
153
+ }
154
+ return fileInfo
113
155
  }
114
156
  }
@@ -1,10 +1,10 @@
1
- package expo.modules.filesystem.next
1
+ package expo.modules.filesystem
2
2
 
3
3
  import expo.modules.kotlin.sharedobjects.SharedRef
4
4
  import java.io.RandomAccessFile
5
5
  import java.nio.ByteBuffer
6
6
  import java.nio.channels.FileChannel
7
- class FileSystemFileHandle(file: FileSystemFile) : SharedRef<FileChannel>(RandomAccessFile(file.file, "rw").channel), AutoCloseable {
7
+ class FileSystemFileHandle(file: FileSystemFile) : SharedRef<FileChannel>(RandomAccessFile(file.javaFile, "rw").channel), AutoCloseable {
8
8
  private val fileChannel: FileChannel = ref
9
9
 
10
10
  private fun ensureIsOpen() {