@amazon-devices/expo-file-system 2.0.1758683737

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 (111) hide show
  1. package/.eslintrc.js +2 -0
  2. package/CHANGELOG.md +317 -0
  3. package/CMakeLists.txt +52 -0
  4. package/LICENSE +7 -0
  5. package/README.kepler.md +260 -0
  6. package/README.md +46 -0
  7. package/THIRD_PARTY_NOTICES.txt +24 -0
  8. package/android/build.gradle +118 -0
  9. package/android/src/main/AndroidManifest.xml +17 -0
  10. package/android/src/main/java/expo/modules/filesystem/AppDirectoriesModule.kt +26 -0
  11. package/android/src/main/java/expo/modules/filesystem/CountingRequestBody.kt +52 -0
  12. package/android/src/main/java/expo/modules/filesystem/FilePermissionModule.kt +48 -0
  13. package/android/src/main/java/expo/modules/filesystem/FileSystemExceptions.kt +48 -0
  14. package/android/src/main/java/expo/modules/filesystem/FileSystemFileProvider.kt +5 -0
  15. package/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt +1110 -0
  16. package/android/src/main/java/expo/modules/filesystem/FileSystemPackage.kt +10 -0
  17. package/android/src/main/java/expo/modules/filesystem/FileSystemRecords.kt +92 -0
  18. package/android/src/main/res/xml/file_system_provider_paths.xml +5 -0
  19. package/app.plugin.js +1 -0
  20. package/build/ExponentFileSystem.d.ts +4 -0
  21. package/build/ExponentFileSystem.d.ts.map +1 -0
  22. package/build/ExponentFileSystem.js +5 -0
  23. package/build/ExponentFileSystem.js.map +1 -0
  24. package/build/ExponentFileSystem.kepler.d.ts +4 -0
  25. package/build/ExponentFileSystem.kepler.d.ts.map +1 -0
  26. package/build/ExponentFileSystem.kepler.js +112 -0
  27. package/build/ExponentFileSystem.kepler.js.map +1 -0
  28. package/build/ExponentFileSystem.web.d.ts +3 -0
  29. package/build/ExponentFileSystem.web.d.ts.map +1 -0
  30. package/build/ExponentFileSystem.web.js +3 -0
  31. package/build/ExponentFileSystem.web.js.map +1 -0
  32. package/build/ExponentFileSystemShim.d.ts +4 -0
  33. package/build/ExponentFileSystemShim.d.ts.map +1 -0
  34. package/build/ExponentFileSystemShim.js +21 -0
  35. package/build/ExponentFileSystemShim.js.map +1 -0
  36. package/build/FileSystem.d.ts +361 -0
  37. package/build/FileSystem.d.ts.map +1 -0
  38. package/build/FileSystem.js +616 -0
  39. package/build/FileSystem.js.map +1 -0
  40. package/build/FileSystem.types.d.ts +304 -0
  41. package/build/FileSystem.types.d.ts.map +1 -0
  42. package/build/FileSystem.types.js +47 -0
  43. package/build/FileSystem.types.js.map +1 -0
  44. package/build/index.d.ts +3 -0
  45. package/build/index.d.ts.map +1 -0
  46. package/build/index.js +3 -0
  47. package/build/index.js.map +1 -0
  48. package/build/types.d.ts +35 -0
  49. package/build/types.d.ts.map +1 -0
  50. package/build/types.js +2 -0
  51. package/build/types.js.map +1 -0
  52. package/expo-module.config.json +11 -0
  53. package/ios/EXFilePermissionModule.h +16 -0
  54. package/ios/EXFilePermissionModule.m +68 -0
  55. package/ios/EXFileSystem.h +25 -0
  56. package/ios/EXFileSystem.m +1084 -0
  57. package/ios/EXFileSystemAssetLibraryHandler.h +6 -0
  58. package/ios/EXFileSystemAssetLibraryHandler.m +142 -0
  59. package/ios/EXFileSystemHandler.h +17 -0
  60. package/ios/EXFileSystemLocalFileHandler.h +7 -0
  61. package/ios/EXFileSystemLocalFileHandler.m +79 -0
  62. package/ios/EXSessionTasks/EXSessionCancelableUploadTaskDelegate.h +16 -0
  63. package/ios/EXSessionTasks/EXSessionCancelableUploadTaskDelegate.m +55 -0
  64. package/ios/EXSessionTasks/EXSessionDownloadTaskDelegate.h +13 -0
  65. package/ios/EXSessionTasks/EXSessionDownloadTaskDelegate.m +64 -0
  66. package/ios/EXSessionTasks/EXSessionHandler.h +19 -0
  67. package/ios/EXSessionTasks/EXSessionHandler.m +49 -0
  68. package/ios/EXSessionTasks/EXSessionResumableDownloadTaskDelegate.h +18 -0
  69. package/ios/EXSessionTasks/EXSessionResumableDownloadTaskDelegate.m +66 -0
  70. package/ios/EXSessionTasks/EXSessionTaskDelegate.h +32 -0
  71. package/ios/EXSessionTasks/EXSessionTaskDelegate.m +58 -0
  72. package/ios/EXSessionTasks/EXSessionTaskDispatcher.h +19 -0
  73. package/ios/EXSessionTasks/EXSessionTaskDispatcher.m +96 -0
  74. package/ios/EXSessionTasks/EXSessionUploadTaskDelegate.h +8 -0
  75. package/ios/EXSessionTasks/EXSessionUploadTaskDelegate.m +52 -0
  76. package/ios/EXSessionTasks/EXTaskHandlersManager.h +21 -0
  77. package/ios/EXSessionTasks/EXTaskHandlersManager.m +56 -0
  78. package/ios/Encoding.swift +88 -0
  79. package/ios/ExpoFileSystem.h +1 -0
  80. package/ios/ExpoFileSystem.podspec +32 -0
  81. package/ios/FileSystemBackgroundSessionHandler.swift +25 -0
  82. package/ios/FileSystemExceptions.swift +69 -0
  83. package/ios/FileSystemHelpers.swift +66 -0
  84. package/ios/FileSystemModule.swift +263 -0
  85. package/ios/FileSystemRecords.swift +74 -0
  86. package/ios/NSData+EXFileSystem.h +9 -0
  87. package/ios/NSData+EXFileSystem.m +19 -0
  88. package/ios/NetworkingHelpers.swift +84 -0
  89. package/ios/Tests/EXFileSystemSpec.swift +55 -0
  90. package/jest.config.js +3 -0
  91. package/kepler/ExponentFileSystem.cpp +498 -0
  92. package/kepler/ExponentFileSystem.h +60 -0
  93. package/kepler/KeplerInit.cpp +28 -0
  94. package/kepler/NetworkingRequestHandler.cpp +47 -0
  95. package/kepler/test/FileSystem.cpp +425 -0
  96. package/package.json +1 -0
  97. package/plugin/build/withFileSystem.d.ts +3 -0
  98. package/plugin/build/withFileSystem.js +12 -0
  99. package/plugin/src/withFileSystem.ts +13 -0
  100. package/plugin/tsconfig.json +9 -0
  101. package/plugin/tsconfig.tsbuildinfo +1 -0
  102. package/react-native.config.js +21 -0
  103. package/src/ExponentFileSystem.kepler.ts +167 -0
  104. package/src/ExponentFileSystem.ts +7 -0
  105. package/src/ExponentFileSystem.web.ts +2 -0
  106. package/src/ExponentFileSystemShim.ts +23 -0
  107. package/src/FileSystem.ts +756 -0
  108. package/src/FileSystem.types.ts +339 -0
  109. package/src/index.ts +2 -0
  110. package/src/types.ts +34 -0
  111. package/tsconfig.json +9 -0
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ <p>
2
+ <a href="https://docs.expo.dev/versions/latest/sdk/filesystem/">
3
+ <img
4
+ src="../../.github/resources/expo-file-system.svg"
5
+ alt="expo-file-system"
6
+ height="64" />
7
+ </a>
8
+ </p>
9
+
10
+ Provides access to the local file system on the device.
11
+
12
+ # API documentation
13
+
14
+ - [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/filesystem.mdx)
15
+ - [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/filesystem/)
16
+
17
+ # API usage clarification
18
+
19
+ - Symbolic links of the directory entries are not followed in `readDirectoryAsync`
20
+
21
+ # Installation in managed Expo projects
22
+
23
+ For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/filesystem/).
24
+
25
+ # Installation in bare React Native projects
26
+
27
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
28
+
29
+ ## Installation in bare iOS React Native project
30
+
31
+ No additional set up necessary.
32
+
33
+ ## Installation in bare Android React Native project
34
+
35
+ This module requires permissions to interact with the filesystem and create resumable downloads. The `READ_EXTERNAL_STORAGE`, `WRITE_EXTERNAL_STORAGE` and `INTERNET` permissions are automatically added.
36
+
37
+ ```xml
38
+ <!-- Added permissions -->
39
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
40
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
41
+ <uses-permission android:name="android.permission.INTERNET" />
42
+ ```
43
+
44
+ # Contributing
45
+
46
+ Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
@@ -0,0 +1,24 @@
1
+ License from package.json:
2
+ ==============================
3
+
4
+ The MIT License (MIT)
5
+
6
+ Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
@@ -0,0 +1,118 @@
1
+ apply plugin: 'com.android.library'
2
+ apply plugin: 'kotlin-android'
3
+ apply plugin: 'maven-publish'
4
+
5
+ group = 'host.exp.exponent'
6
+ version = '15.8.0'
7
+
8
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
9
+ if (expoModulesCorePlugin.exists()) {
10
+ apply from: expoModulesCorePlugin
11
+ applyKotlinExpoModulesCorePlugin()
12
+ // Remove this check, but keep the contents after SDK49 support is dropped
13
+ if (safeExtGet("expoProvidesDefaultConfig", false)) {
14
+ useExpoPublishing()
15
+ useCoreDependencies()
16
+ }
17
+ }
18
+
19
+ buildscript {
20
+ // Simple helper that allows the root project to override versions declared by this library.
21
+ ext.safeExtGet = { prop, fallback ->
22
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
23
+ }
24
+
25
+ // Ensures backward compatibility
26
+ ext.getKotlinVersion = {
27
+ if (ext.has("kotlinVersion")) {
28
+ ext.kotlinVersion()
29
+ } else {
30
+ ext.safeExtGet("kotlinVersion", "1.8.10")
31
+ }
32
+ }
33
+
34
+ repositories {
35
+ mavenCentral()
36
+ }
37
+
38
+ dependencies {
39
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
40
+ }
41
+ }
42
+
43
+ // Remove this if and it's contents, when support for SDK49 is dropped
44
+ if (!safeExtGet("expoProvidesDefaultConfig", false)) {
45
+ afterEvaluate {
46
+ publishing {
47
+ publications {
48
+ release(MavenPublication) {
49
+ from components.release
50
+ }
51
+ }
52
+ repositories {
53
+ maven {
54
+ url = mavenLocal().url
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ android {
62
+ // Remove this if and it's contents, when support for SDK49 is dropped
63
+ if (!safeExtGet("expoProvidesDefaultConfig", false)) {
64
+ compileSdkVersion safeExtGet("compileSdkVersion", 33)
65
+
66
+ defaultConfig {
67
+ minSdkVersion safeExtGet("minSdkVersion", 23)
68
+ targetSdkVersion safeExtGet("targetSdkVersion", 33)
69
+ }
70
+
71
+ publishing {
72
+ singleVariant("release") {
73
+ withSourcesJar()
74
+ }
75
+ }
76
+
77
+ lintOptions {
78
+ abortOnError false
79
+ }
80
+ }
81
+
82
+ def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
83
+ if (agpVersion.tokenize('.')[0].toInteger() < 8) {
84
+ compileOptions {
85
+ sourceCompatibility JavaVersion.VERSION_11
86
+ targetCompatibility JavaVersion.VERSION_11
87
+ }
88
+
89
+ kotlinOptions {
90
+ jvmTarget = JavaVersion.VERSION_11.majorVersion
91
+ }
92
+ }
93
+
94
+ namespace "expo.modules.filesystem"
95
+ defaultConfig {
96
+ versionCode 30
97
+ versionName "15.8.0"
98
+ }
99
+ }
100
+
101
+ repositories {
102
+ mavenCentral()
103
+ }
104
+
105
+ dependencies {
106
+ // Remove this if and it's contents, when support for SDK49 is dropped
107
+ if (!safeExtGet("expoProvidesDefaultConfig", false)) {
108
+ implementation project(':expo-modules-core')
109
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
110
+ }
111
+
112
+ api 'commons-codec:commons-codec:1.10'
113
+ api 'commons-io:commons-io:1.4'
114
+ api 'com.squareup.okhttp3:okhttp:4.9.2'
115
+ api 'com.squareup.okhttp3:okhttp-urlconnection:4.9.2'
116
+ api 'com.squareup.okio:okio:2.9.0'
117
+ api "androidx.legacy:legacy-support-v4:1.0.0"
118
+ }
@@ -0,0 +1,17 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
2
+ <uses-permission android:name="android.permission.INTERNET"/>
3
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
5
+ <application>
6
+ <provider tools:replace="android:authorities" android:name=".FileSystemFileProvider" android:authorities="${applicationId}.FileSystemFileProvider" android:exported="false" android:grantUriPermissions="true">
7
+ <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_system_provider_paths" />
8
+ </provider>
9
+ </application>
10
+
11
+ <queries>
12
+ <!-- Query open documents -->
13
+ <intent>
14
+ <action android:name="android.intent.action.OPEN_DOCUMENT_TREE" />
15
+ </intent>
16
+ </queries>
17
+ </manifest>
@@ -0,0 +1,26 @@
1
+ package expo.modules.filesystem
2
+
3
+ import android.content.Context
4
+ import expo.modules.core.interfaces.InternalModule
5
+ import expo.modules.interfaces.filesystem.AppDirectoriesModuleInterface
6
+ import java.io.File
7
+
8
+ /*
9
+ New Sweet API modules don't have an easy way to access scoped context. We can't initialize them with scoped context as they need a ReactApplicationContext instead.
10
+ We can't make ScopedContext inherit from ReactApplicationContext as that would require moving ScopedContext to versioned and a large refactor.
11
+
12
+ This module is a stopgap solution to provide modules with a way to access ScopedContext directories using the filesystem module, only for our internal modules.
13
+ */
14
+
15
+ // The class needs to be 'open', because it's inherited in expoview
16
+ open class AppDirectoriesModule(private val context: Context) : AppDirectoriesModuleInterface, InternalModule {
17
+
18
+ override fun getExportedInterfaces(): List<Class<*>> =
19
+ listOf(AppDirectoriesModuleInterface::class.java)
20
+
21
+ override val cacheDirectory: File
22
+ get() = context.cacheDir
23
+
24
+ override val persistentFilesDirectory: File
25
+ get() = context.filesDir
26
+ }
@@ -0,0 +1,52 @@
1
+ package expo.modules.filesystem
2
+
3
+ import okhttp3.RequestBody
4
+ import okio.Buffer
5
+ import okio.BufferedSink
6
+ import okio.ForwardingSink
7
+ import okio.Sink
8
+ import okio.buffer
9
+ import java.io.IOException
10
+
11
+ @FunctionalInterface
12
+ fun interface RequestBodyDecorator {
13
+ fun decorate(requestBody: RequestBody): RequestBody
14
+ }
15
+
16
+ @FunctionalInterface
17
+ interface CountingRequestListener {
18
+ fun onProgress(bytesWritten: Long, contentLength: Long)
19
+ }
20
+
21
+ private class CountingSink(
22
+ sink: Sink,
23
+ private val requestBody: RequestBody,
24
+ private val progressListener: CountingRequestListener
25
+ ) : ForwardingSink(sink) {
26
+ private var bytesWritten = 0L
27
+
28
+ override fun write(source: Buffer, byteCount: Long) {
29
+ super.write(source, byteCount)
30
+
31
+ bytesWritten += byteCount
32
+ progressListener.onProgress(bytesWritten, requestBody.contentLength())
33
+ }
34
+ }
35
+
36
+ class CountingRequestBody(
37
+ private val requestBody: RequestBody,
38
+ private val progressListener: CountingRequestListener
39
+ ) : RequestBody() {
40
+ override fun contentType() = requestBody.contentType()
41
+
42
+ @Throws(IOException::class)
43
+ override fun contentLength() = requestBody.contentLength()
44
+
45
+ override fun writeTo(sink: BufferedSink) {
46
+ val countingSink = CountingSink(sink, this, progressListener)
47
+
48
+ val bufferedSink = countingSink.buffer()
49
+ requestBody.writeTo(bufferedSink)
50
+ bufferedSink.flush()
51
+ }
52
+ }
@@ -0,0 +1,48 @@
1
+ package expo.modules.filesystem
2
+
3
+ import android.content.Context
4
+ import expo.modules.interfaces.filesystem.FilePermissionModuleInterface
5
+ import expo.modules.core.interfaces.InternalModule
6
+ import expo.modules.interfaces.filesystem.Permission
7
+ import java.io.File
8
+ import java.io.IOException
9
+ import java.util.*
10
+
11
+ // The class needs to be 'open', because it's inherited in expoview
12
+ open class FilePermissionModule : FilePermissionModuleInterface, InternalModule {
13
+ override fun getExportedInterfaces(): List<Class<*>> =
14
+ listOf(FilePermissionModuleInterface::class.java)
15
+
16
+ override fun getPathPermissions(context: Context, path: String): EnumSet<Permission> =
17
+ getInternalPathPermissions(path, context) ?: getExternalPathPermissions(path)
18
+
19
+ private fun getInternalPathPermissions(path: String, context: Context): EnumSet<Permission>? {
20
+ return try {
21
+ val canonicalPath = File(path).canonicalPath
22
+ getInternalPaths(context)
23
+ .firstOrNull { dir -> canonicalPath.startsWith("$dir/") || dir == canonicalPath }
24
+ ?.let { EnumSet.of(Permission.READ, Permission.WRITE) }
25
+ } catch (e: IOException) {
26
+ EnumSet.noneOf(Permission::class.java)
27
+ }
28
+ }
29
+
30
+ protected open fun getExternalPathPermissions(path: String): EnumSet<Permission> {
31
+ val file = File(path)
32
+ return EnumSet.noneOf(Permission::class.java).apply {
33
+ if (file.canRead()) {
34
+ add(Permission.READ)
35
+ }
36
+ if (file.canWrite()) {
37
+ add(Permission.WRITE)
38
+ }
39
+ }
40
+ }
41
+
42
+ @Throws(IOException::class)
43
+ private fun getInternalPaths(context: Context): List<String> =
44
+ listOf(
45
+ context.filesDir.canonicalPath,
46
+ context.cacheDir.canonicalPath
47
+ )
48
+ }
@@ -0,0 +1,48 @@
1
+ package expo.modules.filesystem
2
+
3
+ import android.net.Uri
4
+ import expo.modules.kotlin.exception.CodedException
5
+
6
+ internal class FileSystemOkHttpNullException :
7
+ CodedException("okHttpClient is null")
8
+
9
+ internal class FileSystemCannotReadDirectoryException(uri: Uri?) :
10
+ CodedException("Uri '$uri' doesn't exist or isn't a directory")
11
+
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
+ )
18
+
19
+ internal class FileSystemUnreadableDirectoryException(uri: String) :
20
+ CodedException("No readable files with the uri '$uri'. Please use other uri")
21
+
22
+ internal class FileSystemCannotCreateFileException(uri: Uri?) :
23
+ CodedException(
24
+ uri?.let {
25
+ "Provided uri '$it' is not pointing to a directory"
26
+ } ?: "Unknown error"
27
+ )
28
+
29
+ internal class FileSystemFileNotFoundException(uri: Uri?) :
30
+ CodedException("File '$uri' could not be deleted because it could not be found")
31
+
32
+ internal class FileSystemPendingPermissionsRequestException :
33
+ CodedException("You have an unfinished permission request")
34
+
35
+ internal class FileSystemCannotMoveFileException(fromUri: Uri, toUri: Uri) :
36
+ CodedException("File '$fromUri' could not be moved to '$toUri'")
37
+
38
+ internal class FileSystemUnsupportedSchemeException :
39
+ CodedException("Can't read Storage Access Framework directory, use StorageAccessFramework.readDirectoryAsync() instead")
40
+
41
+ internal class FileSystemCannotFindTaskException :
42
+ CodedException("Cannot find task")
43
+
44
+ internal class FileSystemCopyFailedException(uri: Uri?) :
45
+ CodedException("File '$uri' could not be copied because it could not be found")
46
+
47
+ internal class CookieHandlerNotFoundException :
48
+ CodedException("Failed to find CookieHandler")
@@ -0,0 +1,5 @@
1
+ package expo.modules.filesystem
2
+
3
+ import androidx.core.content.FileProvider
4
+
5
+ class FileSystemFileProvider : FileProvider()