react-native-cloud-storage 2.2.2 → 3.0.0

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 (216) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/android/build.gradle +88 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/AndroidManifestNew.xml +2 -0
  7. package/android/src/main/java/com/voicekit/CloudStorageError.kt +86 -0
  8. package/android/src/main/java/com/voicekit/CloudStorageLocalFileSystemModule.kt +232 -0
  9. package/android/src/main/java/com/voicekit/CloudStoragePackage.kt +32 -0
  10. package/android/src/main/java/com/voicekit/FileUtils.kt +41 -0
  11. package/android/src/main/java/com/voicekit/Types.kt +6 -0
  12. package/app.plugin.js +1 -1
  13. package/{lib/commonjs/RNCloudStorage.js → dist/commonjs/cloud-storage.js} +177 -92
  14. package/dist/commonjs/cloud-storage.js.map +1 -0
  15. package/dist/commonjs/expo-plugin/index.js +13 -0
  16. package/dist/commonjs/expo-plugin/index.js.map +1 -0
  17. package/{lib/commonjs/expo-plugin/withRNCloudStorageIos.js → dist/commonjs/expo-plugin/ios.js} +1 -1
  18. package/dist/commonjs/expo-plugin/ios.js.map +1 -0
  19. package/{lib/commonjs/hooks/useCloudFile.js → dist/commonjs/hooks/use-cloud-file.js} +26 -8
  20. package/dist/commonjs/hooks/use-cloud-file.js.map +1 -0
  21. package/{lib/commonjs/hooks/useIsCloudAvailable.js → dist/commonjs/hooks/use-is-cloud-available.js} +3 -3
  22. package/dist/commonjs/hooks/use-is-cloud-available.js.map +1 -0
  23. package/{lib → dist}/commonjs/index.js +10 -10
  24. package/dist/commonjs/index.js.map +1 -0
  25. package/dist/commonjs/specs/NativeCloudStorageCloudKitIOS.js +9 -0
  26. package/dist/commonjs/specs/NativeCloudStorageCloudKitIOS.js.map +1 -0
  27. package/dist/commonjs/specs/NativeCloudStorageLocalFileSystem.js +9 -0
  28. package/dist/commonjs/specs/NativeCloudStorageLocalFileSystem.js.map +1 -0
  29. package/dist/commonjs/storages/cloudkit.js +12 -0
  30. package/dist/commonjs/storages/cloudkit.js.map +1 -0
  31. package/{lib/commonjs → dist/commonjs/storages}/google-drive/client.js +83 -40
  32. package/dist/commonjs/storages/google-drive/client.js.map +1 -0
  33. package/dist/commonjs/storages/google-drive/index.js +399 -0
  34. package/dist/commonjs/storages/google-drive/index.js.map +1 -0
  35. package/dist/commonjs/storages/google-drive/types.js.map +1 -0
  36. package/{lib → dist}/commonjs/types/main.js.map +1 -1
  37. package/dist/commonjs/types/native.js +28 -0
  38. package/dist/commonjs/types/native.js.map +1 -0
  39. package/{lib/commonjs/utils/CloudStorageError.js → dist/commonjs/utils/cloud-storage-error.js} +3 -1
  40. package/dist/commonjs/utils/cloud-storage-error.js.map +1 -0
  41. package/dist/commonjs/utils/constants.js +25 -0
  42. package/dist/commonjs/utils/constants.js.map +1 -0
  43. package/dist/commonjs/utils/local-fs.js +17 -0
  44. package/dist/commonjs/utils/local-fs.js.map +1 -0
  45. package/dist/commonjs/utils/native.js +35 -0
  46. package/dist/commonjs/utils/native.js.map +1 -0
  47. package/{lib/module/RNCloudStorage.js → dist/module/cloud-storage.js} +178 -93
  48. package/dist/module/cloud-storage.js.map +1 -0
  49. package/dist/module/expo-plugin/index.js +8 -0
  50. package/dist/module/expo-plugin/index.js.map +1 -0
  51. package/{lib/module/expo-plugin/withRNCloudStorageIos.js → dist/module/expo-plugin/ios.js} +1 -1
  52. package/dist/module/expo-plugin/ios.js.map +1 -0
  53. package/{lib/module/hooks/useCloudFile.js → dist/module/hooks/use-cloud-file.js} +25 -7
  54. package/dist/module/hooks/use-cloud-file.js.map +1 -0
  55. package/{lib/module/hooks/useIsCloudAvailable.js → dist/module/hooks/use-is-cloud-available.js} +2 -2
  56. package/dist/module/hooks/use-is-cloud-available.js.map +1 -0
  57. package/dist/module/index.js +9 -0
  58. package/dist/module/index.js.map +1 -0
  59. package/dist/module/specs/NativeCloudStorageCloudKitIOS.js +5 -0
  60. package/dist/module/specs/NativeCloudStorageCloudKitIOS.js.map +1 -0
  61. package/dist/module/specs/NativeCloudStorageLocalFileSystem.js +5 -0
  62. package/dist/module/specs/NativeCloudStorageLocalFileSystem.js.map +1 -0
  63. package/dist/module/storages/cloudkit.js +7 -0
  64. package/dist/module/storages/cloudkit.js.map +1 -0
  65. package/{lib/module → dist/module/storages}/google-drive/client.js +83 -40
  66. package/dist/module/storages/google-drive/client.js.map +1 -0
  67. package/dist/module/storages/google-drive/index.js +392 -0
  68. package/dist/module/storages/google-drive/index.js.map +1 -0
  69. package/dist/module/storages/google-drive/types.js.map +1 -0
  70. package/{lib → dist}/module/types/main.js.map +1 -1
  71. package/dist/module/types/native.js +24 -0
  72. package/dist/module/types/native.js.map +1 -0
  73. package/{lib/module/utils/CloudStorageError.js → dist/module/utils/cloud-storage-error.js} +3 -1
  74. package/dist/module/utils/cloud-storage-error.js.map +1 -0
  75. package/dist/module/utils/constants.js +21 -0
  76. package/dist/module/utils/constants.js.map +1 -0
  77. package/dist/module/utils/local-fs.js +12 -0
  78. package/dist/module/utils/local-fs.js.map +1 -0
  79. package/dist/module/utils/native.js +30 -0
  80. package/dist/module/utils/native.js.map +1 -0
  81. package/{lib/typescript/RNCloudStorage.d.ts → dist/typescript/cloud-storage.d.ts} +67 -8
  82. package/dist/typescript/cloud-storage.d.ts.map +1 -0
  83. package/{lib/typescript/expo-plugin/withRNCloudStorage.d.ts → dist/typescript/expo-plugin/index.d.ts} +1 -1
  84. package/dist/typescript/expo-plugin/index.d.ts.map +1 -0
  85. package/{lib/typescript/expo-plugin/withRNCloudStorageIos.d.ts → dist/typescript/expo-plugin/ios.d.ts} +1 -1
  86. package/dist/typescript/expo-plugin/ios.d.ts.map +1 -0
  87. package/{lib/typescript/hooks/useCloudFile.d.ts → dist/typescript/hooks/use-cloud-file.d.ts} +22 -4
  88. package/dist/typescript/hooks/use-cloud-file.d.ts.map +1 -0
  89. package/{lib/typescript/hooks/useIsCloudAvailable.d.ts → dist/typescript/hooks/use-is-cloud-available.d.ts} +2 -2
  90. package/dist/typescript/hooks/use-is-cloud-available.d.ts.map +1 -0
  91. package/dist/typescript/index.d.ts +7 -0
  92. package/dist/typescript/index.d.ts.map +1 -0
  93. package/dist/typescript/specs/NativeCloudStorageCloudKitIOS.d.ts +30 -0
  94. package/dist/typescript/specs/NativeCloudStorageCloudKitIOS.d.ts.map +1 -0
  95. package/dist/typescript/specs/NativeCloudStorageLocalFileSystem.d.ts +24 -0
  96. package/dist/typescript/specs/NativeCloudStorageLocalFileSystem.d.ts.map +1 -0
  97. package/dist/typescript/storages/cloudkit.d.ts +6 -0
  98. package/dist/typescript/storages/cloudkit.d.ts.map +1 -0
  99. package/{lib/typescript → dist/typescript/storages}/google-drive/client.d.ts +10 -3
  100. package/dist/typescript/storages/google-drive/client.d.ts.map +1 -0
  101. package/dist/typescript/storages/google-drive/index.d.ts +41 -0
  102. package/dist/typescript/storages/google-drive/index.d.ts.map +1 -0
  103. package/dist/typescript/storages/google-drive/types.d.ts.map +1 -0
  104. package/{lib → dist}/typescript/types/main.d.ts +8 -0
  105. package/dist/typescript/types/main.d.ts.map +1 -0
  106. package/dist/typescript/types/native.d.ts +27 -0
  107. package/dist/typescript/types/native.d.ts.map +1 -0
  108. package/dist/typescript/utils/cloud-storage-error.d.ts +8 -0
  109. package/dist/typescript/utils/cloud-storage-error.d.ts.map +1 -0
  110. package/dist/typescript/utils/constants.d.ts +4 -0
  111. package/dist/typescript/utils/constants.d.ts.map +1 -0
  112. package/{lib → dist}/typescript/utils/helpers.d.ts.map +1 -1
  113. package/dist/typescript/utils/local-fs.d.ts +2 -0
  114. package/dist/typescript/utils/local-fs.d.ts.map +1 -0
  115. package/dist/typescript/utils/native.d.ts +7 -0
  116. package/dist/typescript/utils/native.d.ts.map +1 -0
  117. package/ios/CloudStorage-Bridging-Header.h +0 -1
  118. package/ios/CloudStorage.xcodeproj/project.pbxproj +12 -6
  119. package/ios/CloudStorageCloudKit.swift +159 -0
  120. package/ios/CloudStorageLocalFileSystem.swift +216 -0
  121. package/ios/RCTCloudStorageCloudKit.mm +209 -0
  122. package/ios/RCTCloudStorageLocalFileSystem.mm +149 -0
  123. package/ios/Utils/CloudKitUtils.swift +12 -6
  124. package/ios/Utils/CloudStorageError.swift +8 -0
  125. package/ios/Utils/FileUtils.swift +21 -4
  126. package/ios/Utils/Promise.swift +1 -0
  127. package/ios/Utils/Types.swift +8 -1
  128. package/ios/react_native_cloud_storage.h +6 -0
  129. package/package.json +64 -110
  130. package/react-native-cloud-storage.podspec +2 -0
  131. package/src/{RNCloudStorage.ts → cloud-storage.ts} +210 -100
  132. package/src/expo-plugin/{withRNCloudStorage.ts → index.ts} +2 -2
  133. package/src/hooks/{useCloudFile.ts → use-cloud-file.ts} +24 -6
  134. package/src/hooks/{useIsCloudAvailable.ts → use-is-cloud-available.ts} +1 -1
  135. package/src/index.ts +5 -6
  136. package/src/specs/NativeCloudStorageCloudKitIOS.ts +33 -0
  137. package/src/specs/NativeCloudStorageLocalFileSystem.ts +28 -0
  138. package/src/storages/cloudkit.ts +13 -0
  139. package/src/{google-drive → storages/google-drive}/client.ts +100 -41
  140. package/src/storages/google-drive/index.ts +488 -0
  141. package/src/types/main.ts +9 -0
  142. package/src/types/native.ts +14 -22
  143. package/src/utils/cloud-storage-error.ts +15 -0
  144. package/src/utils/constants.ts +21 -0
  145. package/src/utils/local-fs.ts +19 -0
  146. package/src/utils/native.ts +40 -0
  147. package/ios/CloudStorage.m +0 -22
  148. package/ios/CloudStorage.swift +0 -103
  149. package/ios/CloudStorageEventEmitter.m +0 -16
  150. package/ios/CloudStorageEventEmitter.swift +0 -30
  151. package/lib/commonjs/RNCloudStorage.js.map +0 -1
  152. package/lib/commonjs/expo-plugin/withRNCloudStorage.js +0 -13
  153. package/lib/commonjs/expo-plugin/withRNCloudStorage.js.map +0 -1
  154. package/lib/commonjs/expo-plugin/withRNCloudStorageIos.js.map +0 -1
  155. package/lib/commonjs/google-drive/client.js.map +0 -1
  156. package/lib/commonjs/google-drive/index.js +0 -321
  157. package/lib/commonjs/google-drive/index.js.map +0 -1
  158. package/lib/commonjs/google-drive/types.js.map +0 -1
  159. package/lib/commonjs/hooks/useCloudFile.js.map +0 -1
  160. package/lib/commonjs/hooks/useIsCloudAvailable.js.map +0 -1
  161. package/lib/commonjs/index.js.map +0 -1
  162. package/lib/commonjs/types/native.js +0 -26
  163. package/lib/commonjs/types/native.js.map +0 -1
  164. package/lib/commonjs/utils/CloudStorageError.js.map +0 -1
  165. package/lib/module/RNCloudStorage.js.map +0 -1
  166. package/lib/module/expo-plugin/withRNCloudStorage.js +0 -8
  167. package/lib/module/expo-plugin/withRNCloudStorage.js.map +0 -1
  168. package/lib/module/expo-plugin/withRNCloudStorageIos.js.map +0 -1
  169. package/lib/module/google-drive/client.js.map +0 -1
  170. package/lib/module/google-drive/index.js +0 -313
  171. package/lib/module/google-drive/index.js.map +0 -1
  172. package/lib/module/google-drive/types.js.map +0 -1
  173. package/lib/module/hooks/useCloudFile.js.map +0 -1
  174. package/lib/module/hooks/useIsCloudAvailable.js.map +0 -1
  175. package/lib/module/index.js +0 -10
  176. package/lib/module/index.js.map +0 -1
  177. package/lib/module/types/native.js +0 -22
  178. package/lib/module/types/native.js.map +0 -1
  179. package/lib/module/utils/CloudStorageError.js.map +0 -1
  180. package/lib/typescript/RNCloudStorage.d.ts.map +0 -1
  181. package/lib/typescript/expo-plugin/withRNCloudStorage.d.ts.map +0 -1
  182. package/lib/typescript/expo-plugin/withRNCloudStorageIos.d.ts.map +0 -1
  183. package/lib/typescript/google-drive/client.d.ts.map +0 -1
  184. package/lib/typescript/google-drive/index.d.ts +0 -34
  185. package/lib/typescript/google-drive/index.d.ts.map +0 -1
  186. package/lib/typescript/google-drive/types.d.ts.map +0 -1
  187. package/lib/typescript/hooks/useCloudFile.d.ts.map +0 -1
  188. package/lib/typescript/hooks/useIsCloudAvailable.d.ts.map +0 -1
  189. package/lib/typescript/index.d.ts +0 -8
  190. package/lib/typescript/index.d.ts.map +0 -1
  191. package/lib/typescript/types/main.d.ts.map +0 -1
  192. package/lib/typescript/types/native.d.ts +0 -40
  193. package/lib/typescript/types/native.d.ts.map +0 -1
  194. package/lib/typescript/utils/CloudStorageError.d.ts +0 -8
  195. package/lib/typescript/utils/CloudStorageError.d.ts.map +0 -1
  196. package/src/google-drive/index.ts +0 -399
  197. package/src/utils/CloudStorageError.ts +0 -14
  198. /package/{lib → dist}/commonjs/expo-plugin/types/index.js +0 -0
  199. /package/{lib → dist}/commonjs/expo-plugin/types/index.js.map +0 -0
  200. /package/{lib/commonjs → dist/commonjs/storages}/google-drive/types.js +0 -0
  201. /package/{lib → dist}/commonjs/types/main.js +0 -0
  202. /package/{lib → dist}/commonjs/utils/helpers.js +0 -0
  203. /package/{lib → dist}/commonjs/utils/helpers.js.map +0 -0
  204. /package/{lib → dist}/module/expo-plugin/types/index.js +0 -0
  205. /package/{lib → dist}/module/expo-plugin/types/index.js.map +0 -0
  206. /package/{lib → dist}/module/package.json +0 -0
  207. /package/{lib/module → dist/module/storages}/google-drive/types.js +0 -0
  208. /package/{lib → dist}/module/types/main.js +0 -0
  209. /package/{lib → dist}/module/utils/helpers.js +0 -0
  210. /package/{lib → dist}/module/utils/helpers.js.map +0 -0
  211. /package/{lib → dist}/typescript/expo-plugin/types/index.d.ts +0 -0
  212. /package/{lib → dist}/typescript/expo-plugin/types/index.d.ts.map +0 -0
  213. /package/{lib/typescript → dist/typescript/storages}/google-drive/types.d.ts +0 -0
  214. /package/{lib → dist}/typescript/utils/helpers.d.ts +0 -0
  215. /package/src/expo-plugin/{withRNCloudStorageIos.ts → ios.ts} +0 -0
  216. /package/src/{google-drive → storages/google-drive}/types.ts +0 -0
@@ -0,0 +1,159 @@
1
+ import Foundation
2
+ import React
3
+
4
+ @objc(CloudStorageCloudKit)
5
+ public class CloudStorageCloudKit: NSObject {
6
+ @objc(fileExists:withScope:withResolver:withRejecter:)
7
+ public func fileExists(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
8
+ withPromise(resolve: resolve, reject: reject) {
9
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
10
+ return try FileUtils.checkFileExists(fileUrl: fileUrl)
11
+ }
12
+ }
13
+
14
+ @objc(appendToFile:withData:withScope:withResolver:withRejecter:)
15
+ public func appendToFile(path: String, data: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
16
+ withPromise(resolve: resolve, reject: reject) {
17
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
18
+
19
+ var existingData = ""
20
+ if try FileUtils.checkFileExists(fileUrl: fileUrl) {
21
+ existingData = try FileUtils.readFile(fileUrl: fileUrl)
22
+ }
23
+
24
+ let newData = existingData + data
25
+ return try FileUtils.writeFile(fileUrl: fileUrl, content: newData)
26
+ }
27
+ }
28
+
29
+ @objc(createFile:withData:withScope:withOverwrite:withResolver:withRejecter:)
30
+ public func createFile(path: String, data: String, scope: String, overwrite: Bool, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
31
+ withPromise(resolve: resolve, reject: reject) {
32
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
33
+
34
+ if try (FileUtils.checkFileExists(fileUrl: fileUrl) && !overwrite) {
35
+ throw CloudStorageError.fileAlreadyExists(path: path)
36
+ }
37
+
38
+ return try FileUtils.writeFile(fileUrl: fileUrl, content: data)
39
+ }
40
+ }
41
+
42
+ @objc(createDirectory:withScope:withResolver:withRejecter:)
43
+ public func createDirectory(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
44
+ withPromise(resolve: resolve, reject: reject) {
45
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
46
+ return try FileUtils.createDirectory(directoryUrl: fileUrl)
47
+ }
48
+ }
49
+
50
+ @objc(listFiles:withScope:withResolver:withRejecter:)
51
+ public func listFiles(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
52
+ withPromise(resolve: resolve, reject: reject) {
53
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
54
+ return try FileUtils.listFiles(directoryUrl: fileUrl)
55
+ }
56
+ }
57
+
58
+ @objc(readFile:withScope:withResolver:withRejecter:)
59
+ public func readFile(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
60
+ withPromise(resolve: resolve, reject: reject) {
61
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
62
+ return try FileUtils.readFile(fileUrl: fileUrl)
63
+ }
64
+ }
65
+
66
+ @objc(triggerSync:withScope:withResolver:withRejecter:)
67
+ public func triggerSync(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
68
+ withPromise(resolve: resolve, reject: reject) {
69
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
70
+ return try CloudKitUtils.triggerSync(fileUrl: fileUrl)
71
+ }
72
+ }
73
+
74
+ @objc(deleteFile:withScope:withResolver:withRejecter:)
75
+ public func deleteFile(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
76
+ withPromise(resolve: resolve, reject: reject) {
77
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
78
+ return try FileUtils.deleteFileOrDirectory(fileUrl: fileUrl)
79
+ }
80
+ }
81
+
82
+ @objc(deleteDirectory:withRecursive:withScope:withResolver:withRejecter:)
83
+ public func deleteDirectory(path: String, recursive _: Bool, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
84
+ withPromise(resolve: resolve, reject: reject) {
85
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
86
+ return try FileUtils.deleteFileOrDirectory(fileUrl: fileUrl)
87
+ }
88
+ }
89
+
90
+ @objc(statFile:withScope:withResolver:withRejecter:)
91
+ public func statFile(path: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
92
+ withPromise(resolve: resolve, reject: reject) {
93
+ let fileUrl = try CloudKitUtils.getFileURL(path: path, scope: scope)
94
+ return try FileUtils.statFile(fileUrl: fileUrl).toDictionary()
95
+ }
96
+ }
97
+
98
+ @objc(downloadFile:withLocalPath:withScope:withResolver:withRejecter:)
99
+ public func downloadFile(remotePath: String, localPath: String, scope: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
100
+ withPromise(resolve: resolve, reject: reject) {
101
+ let sourceUrl = try CloudKitUtils.getFileURL(path: remotePath, scope: scope, true)
102
+
103
+ let sourceStat = try FileUtils.statFile(fileUrl: sourceUrl)
104
+ if sourceStat.isDirectory {
105
+ throw CloudStorageError.pathIsDirectory(path: remotePath)
106
+ }
107
+
108
+ let destinationUrl = URL(fileURLWithPath: localPath)
109
+ let destinationDirectoryUrl = destinationUrl.deletingLastPathComponent()
110
+
111
+ if try !FileUtils.checkFileExists(fileUrl: destinationDirectoryUrl) {
112
+ throw CloudStorageError.directoryNotFound(path: destinationDirectoryUrl.path)
113
+ }
114
+
115
+ let destDirStat = try FileUtils.statFile(fileUrl: destinationDirectoryUrl)
116
+ if !destDirStat.isDirectory {
117
+ throw CloudStorageError.pathIsFile(path: destinationDirectoryUrl.path)
118
+ }
119
+
120
+ if try FileUtils.checkFileExists(fileUrl: destinationUrl) {
121
+ throw CloudStorageError.fileAlreadyExists(path: localPath)
122
+ }
123
+
124
+ return try FileUtils.copyFile(from: sourceUrl, to: destinationUrl)
125
+ }
126
+ }
127
+
128
+ @objc(uploadFile:withLocalPath:withMimeType:withScope:withOverwrite:withResolver:withRejecter:)
129
+ public func uploadFile(remotePath: String, localPath: String, mimeType _: String, scope: String, overwrite: Bool, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
130
+ withPromise(resolve: resolve, reject: reject) {
131
+ let destinationUrl = try CloudKitUtils.getFileURL(path: remotePath, scope: scope)
132
+ let sourceUrl = URL(fileURLWithPath: localPath)
133
+
134
+ if try !FileUtils.checkFileExists(fileUrl: sourceUrl) {
135
+ throw CloudStorageError.fileNotFound(path: localPath)
136
+ }
137
+
138
+ let destinationDirectoryUrl = destinationUrl.deletingLastPathComponent()
139
+ try FileUtils.createDirectory(directoryUrl: destinationDirectoryUrl)
140
+
141
+ if try FileUtils.checkFileExists(fileUrl: destinationUrl) {
142
+ if overwrite {
143
+ try FileUtils.deleteFileOrDirectory(fileUrl: destinationUrl)
144
+ } else {
145
+ throw CloudStorageError.fileAlreadyExists(path: remotePath)
146
+ }
147
+ }
148
+
149
+ return try FileUtils.copyFile(from: sourceUrl, to: destinationUrl)
150
+ }
151
+ }
152
+
153
+ @objc(isCloudAvailable:withRejecter:)
154
+ public func isCloudAvailable(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
155
+ withPromise(resolve: resolve, reject: reject) {
156
+ CloudKitUtils.isCloudKitAvailable()
157
+ }
158
+ }
159
+ }
@@ -0,0 +1,216 @@
1
+ import Foundation
2
+ import MobileCoreServices
3
+ import React
4
+
5
+ // MARK: - CloudStorageLocalFileSystem
6
+
7
+ @objc(CloudStorageLocalFileSystem)
8
+ public class CloudStorageLocalFileSystem: NSObject {
9
+ @objc
10
+ public func constantsToExport() -> [AnyHashable: Any]! {
11
+ [
12
+ "temporaryDirectory": FileUtils.temporaryDirectory.path,
13
+ ]
14
+ }
15
+
16
+ @objc(createFile:withData:withResolver:withRejecter:)
17
+ public func createFile(path: String, data: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
18
+ withPromise(resolve: resolve, reject: reject) {
19
+ let fileUrl = URL(fileURLWithPath: path)
20
+ let directoryUrl = fileUrl.deletingLastPathComponent()
21
+
22
+ var isDirectory: ObjCBool = false
23
+ if !FileManager.default.fileExists(atPath: directoryUrl.path, isDirectory: &isDirectory) {
24
+ throw CloudStorageError.directoryNotFound(path: directoryUrl.path)
25
+ }
26
+
27
+ if !isDirectory.boolValue {
28
+ throw CloudStorageError.pathIsFile(path: directoryUrl.path)
29
+ }
30
+
31
+ try FileUtils.writeFile(fileUrl: fileUrl, content: data)
32
+ return fileUrl.path
33
+ }
34
+ }
35
+
36
+ @objc(readFile:withResolver:withRejecter:)
37
+ public func readFile(path: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
38
+ withPromise(resolve: resolve, reject: reject) {
39
+ let fileUrl = URL(fileURLWithPath: path)
40
+ return try FileUtils.readFile(fileUrl: fileUrl)
41
+ }
42
+ }
43
+
44
+ @objc(downloadFile:withLocalPath:withOptions:withResolver:withRejecter:)
45
+ public func downloadFile(remoteUri: String, localPath: String, options: [String: Any]?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
46
+ guard let remoteUrl = URL(string: remoteUri) else {
47
+ let error = CloudStorageError.invalidUrl(url: remoteUri)
48
+ reject(error.code, error.message, nil)
49
+ return
50
+ }
51
+
52
+ let sanitizedPath = sanitizePath(localPath)
53
+ let localUrl = URL(fileURLWithPath: sanitizedPath)
54
+
55
+ let configuration = URLSessionConfiguration.default
56
+ if let headers = options?["headers"] as? [String: String] {
57
+ configuration.httpAdditionalHeaders = headers
58
+ }
59
+ let session = URLSession(configuration: configuration)
60
+
61
+ let downloadTask = session.downloadTask(with: remoteUrl) { tempLocalUrl, _, error in
62
+ if let error {
63
+ let nsError = error as NSError
64
+ let cloudError = CloudStorageError.networkError(message: "Download error for path \(remoteUri): \(nsError.localizedDescription)")
65
+ reject(cloudError.code, cloudError.message, nsError)
66
+ return
67
+ }
68
+
69
+ guard let tempLocalUrl else {
70
+ let cloudError = CloudStorageError.unknown(message: "Download failed: temporary file location is missing.")
71
+ reject(cloudError.code, cloudError.message, nil)
72
+ return
73
+ }
74
+
75
+ do {
76
+ let directory = localUrl.deletingLastPathComponent()
77
+ try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)
78
+
79
+ if FileManager.default.fileExists(atPath: localUrl.path) {
80
+ try FileManager.default.removeItem(at: localUrl)
81
+ }
82
+
83
+ try FileManager.default.moveItem(at: tempLocalUrl, to: localUrl)
84
+ resolve(nil)
85
+ } catch {
86
+ let nsError = error as NSError
87
+ let cloudError = CloudStorageError.writeError(path: localUrl.path)
88
+ reject(cloudError.code, cloudError.message, nsError)
89
+ }
90
+ }
91
+
92
+ downloadTask.resume()
93
+ }
94
+
95
+ @objc(uploadFile:withRemoteUri:withOptions:withResolver:withRejecter:)
96
+ public func uploadFile(localPath: String, remoteUri: String, options: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
97
+ guard let remoteUrl = URL(string: remoteUri) else {
98
+ let error = CloudStorageError.invalidUrl(url: remoteUri)
99
+ reject(error.code, error.message, nil)
100
+ return
101
+ }
102
+
103
+ let sanitizedPath = sanitizePath(localPath)
104
+ let localUrl = URL(fileURLWithPath: sanitizedPath)
105
+
106
+ guard let uploadTypeString = options["uploadType"] as? String,
107
+ let uploadType = UploadType(rawValue: uploadTypeString) else {
108
+ let error = CloudStorageError.unknown(message: "uploadType is required and must be either 'multipart' or 'binary'")
109
+ reject(error.code, error.message, nil)
110
+ return
111
+ }
112
+
113
+ var request = URLRequest(url: remoteUrl)
114
+ request.httpMethod = (options["method"] as? String)?.uppercased() ?? "POST"
115
+
116
+ if let headers = options["headers"] as? [String: String] {
117
+ for (key, value) in headers {
118
+ request.setValue(value, forHTTPHeaderField: key)
119
+ }
120
+ }
121
+
122
+ do {
123
+ let fileData = try Data(contentsOf: localUrl)
124
+
125
+ switch uploadType {
126
+ case .binary:
127
+ request.httpBody = fileData
128
+ if request.value(forHTTPHeaderField: "Content-Type") == nil {
129
+ request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
130
+ }
131
+ case .multipart:
132
+ guard let fieldName = options["fieldName"] as? String else {
133
+ let error = CloudStorageError.unknown(message: "fieldName is required for multipart uploads")
134
+ reject(error.code, error.message, nil)
135
+ return
136
+ }
137
+
138
+ let boundary = "Boundary-\(UUID().uuidString)"
139
+ request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
140
+
141
+ var body = Data()
142
+ let lineBreak = "\r\n"
143
+
144
+ if let parameters = options["parameters"] as? [String: String] {
145
+ for (key, value) in parameters {
146
+ body.append("--\(boundary)\(lineBreak)")
147
+ body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak)\(lineBreak)")
148
+ body.append("\(value)\(lineBreak)")
149
+ }
150
+ }
151
+
152
+ body.append("--\(boundary)\(lineBreak)")
153
+ body.append("Content-Disposition: form-data; name=\"\(fieldName)\"; filename=\"\(localUrl.lastPathComponent)\"\(lineBreak)")
154
+ if let mimeType = getMimeType(for: localUrl) {
155
+ body.append("Content-Type: \(mimeType)\(lineBreak)\(lineBreak)")
156
+ } else {
157
+ body.append("Content-Type: application/octet-stream\(lineBreak)\(lineBreak)")
158
+ }
159
+ body.append(fileData)
160
+ body.append(lineBreak)
161
+ body.append("--\(boundary)--\(lineBreak)")
162
+
163
+ request.httpBody = body
164
+ }
165
+
166
+ let task = URLSession.shared.dataTask(with: request) { _, response, error in
167
+ if let error {
168
+ let nsError = error as NSError
169
+ let cloudError = CloudStorageError.networkError(message: "Upload error for path \(sanitizedPath): \(nsError.localizedDescription)")
170
+ reject(cloudError.code, cloudError.message, nsError)
171
+ return
172
+ }
173
+
174
+ guard let httpResponse = response as? HTTPURLResponse, (200 ... 299).contains(httpResponse.statusCode) else {
175
+ let httpResponse = response as? HTTPURLResponse
176
+ let message = "Upload failed for path \(sanitizedPath) with status code: \(httpResponse?.statusCode ?? -1)"
177
+ let cloudError = CloudStorageError.networkError(message: message)
178
+ reject(cloudError.code, cloudError.message, nil)
179
+ return
180
+ }
181
+
182
+ resolve(nil)
183
+ }
184
+ task.resume()
185
+ } catch {
186
+ let nsError = error as NSError
187
+ let cloudError = CloudStorageError.readError(path: sanitizedPath)
188
+ reject(cloudError.code, cloudError.message, nsError)
189
+ }
190
+ }
191
+
192
+ private func sanitizePath(_ path: String) -> String {
193
+ if path.hasPrefix("file://") {
194
+ return String(path.dropFirst("file://".count))
195
+ }
196
+ return path
197
+ }
198
+
199
+ private func getMimeType(for url: URL) -> String? {
200
+ let pathExtension = url.pathExtension
201
+ if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue() {
202
+ if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
203
+ return mimetype as String
204
+ }
205
+ }
206
+ return nil
207
+ }
208
+ }
209
+
210
+ extension Data {
211
+ mutating func append(_ string: String) {
212
+ if let data = string.data(using: .utf8) {
213
+ append(data)
214
+ }
215
+ }
216
+ }
@@ -0,0 +1,209 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ #import <CloudStorageSpec/CloudStorageSpec.h>
4
+
5
+ #if __has_include("react_native_cloud_storage-Swift.h")
6
+ #import "react_native_cloud_storage-Swift.h"
7
+ #elif __has_include(<react_native_cloud_storage/react_native_cloud_storage-Swift.h>)
8
+ #import <react_native_cloud_storage/react_native_cloud_storage-Swift.h>
9
+ #else
10
+ #error "Unable to locate Swift compatibility header for react-native-cloud-storage."
11
+ #endif
12
+
13
+ @interface RCTCloudStorageCloudKit : NativeCloudStorageCloudKitIOSSpecBase <NativeCloudStorageCloudKitIOSSpec>
14
+ @end
15
+
16
+ @implementation RCTCloudStorageCloudKit {
17
+ CloudStorageCloudKit *_cloudStorageCloudKit;
18
+ id<NSObject> _ubiquityIdentityObserver;
19
+ }
20
+
21
+ + (NSString *)moduleName
22
+ {
23
+ return @"CloudStorageCloudKit";
24
+ }
25
+
26
+ + (BOOL)requiresMainQueueSetup
27
+ {
28
+ return NO;
29
+ }
30
+
31
+ - (instancetype)init
32
+ {
33
+ if (self = [super init]) {
34
+ _cloudStorageCloudKit = [CloudStorageCloudKit new];
35
+
36
+ __weak __typeof__(self) weakSelf = self;
37
+ _ubiquityIdentityObserver = [[NSNotificationCenter defaultCenter]
38
+ addObserverForName:NSUbiquityIdentityDidChangeNotification
39
+ object:nil
40
+ queue:nil
41
+ usingBlock:^(__unused NSNotification *notification) {
42
+ __strong __typeof__(weakSelf) strongSelf = weakSelf;
43
+ [strongSelf emitCloudAvailabilityChanged];
44
+ }];
45
+ }
46
+
47
+ return self;
48
+ }
49
+
50
+ - (void)dealloc
51
+ {
52
+ if (_ubiquityIdentityObserver != nil) {
53
+ [[NSNotificationCenter defaultCenter] removeObserver:_ubiquityIdentityObserver];
54
+ _ubiquityIdentityObserver = nil;
55
+ }
56
+ }
57
+
58
+ - (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper
59
+ {
60
+ [super setEventEmitterCallback:eventEmitterCallbackWrapper];
61
+ [self emitCloudAvailabilityChanged];
62
+ }
63
+
64
+ - (void)emitCloudAvailabilityChanged
65
+ {
66
+ BOOL isCloudAvailable = [NSFileManager defaultManager].ubiquityIdentityToken != nil;
67
+ [self emitOnCloudAvailabilityChanged:@{ @"available" : @(isCloudAvailable) }];
68
+ }
69
+
70
+ - (void)fileExists:(NSString *)path
71
+ scope:(NSString *)scope
72
+ resolve:(RCTPromiseResolveBlock)resolve
73
+ reject:(RCTPromiseRejectBlock)reject
74
+ {
75
+ [_cloudStorageCloudKit fileExists:path withScope:scope withResolver:resolve withRejecter:reject];
76
+ }
77
+
78
+ - (void)appendToFile:(NSString *)path
79
+ data:(NSString *)data
80
+ scope:(NSString *)scope
81
+ resolve:(RCTPromiseResolveBlock)resolve
82
+ reject:(RCTPromiseRejectBlock)reject
83
+ {
84
+ [_cloudStorageCloudKit appendToFile:path withData:data withScope:scope withResolver:resolve withRejecter:reject];
85
+ }
86
+
87
+ - (void)createFile:(NSString *)path
88
+ data:(NSString *)data
89
+ scope:(NSString *)scope
90
+ overwrite:(BOOL)overwrite
91
+ resolve:(RCTPromiseResolveBlock)resolve
92
+ reject:(RCTPromiseRejectBlock)reject
93
+ {
94
+ [_cloudStorageCloudKit
95
+ createFile:path
96
+ withData:data
97
+ withScope:scope
98
+ withOverwrite:overwrite
99
+ withResolver:resolve
100
+ withRejecter:reject];
101
+ }
102
+
103
+ - (void)createDirectory:(NSString *)path
104
+ scope:(NSString *)scope
105
+ resolve:(RCTPromiseResolveBlock)resolve
106
+ reject:(RCTPromiseRejectBlock)reject
107
+ {
108
+ [_cloudStorageCloudKit createDirectory:path withScope:scope withResolver:resolve withRejecter:reject];
109
+ }
110
+
111
+ - (void)listFiles:(NSString *)path
112
+ scope:(NSString *)scope
113
+ resolve:(RCTPromiseResolveBlock)resolve
114
+ reject:(RCTPromiseRejectBlock)reject
115
+ {
116
+ [_cloudStorageCloudKit listFiles:path withScope:scope withResolver:resolve withRejecter:reject];
117
+ }
118
+
119
+ - (void)readFile:(NSString *)path
120
+ scope:(NSString *)scope
121
+ resolve:(RCTPromiseResolveBlock)resolve
122
+ reject:(RCTPromiseRejectBlock)reject
123
+ {
124
+ [_cloudStorageCloudKit readFile:path withScope:scope withResolver:resolve withRejecter:reject];
125
+ }
126
+
127
+ - (void)triggerSync:(NSString *)path
128
+ scope:(NSString *)scope
129
+ resolve:(RCTPromiseResolveBlock)resolve
130
+ reject:(RCTPromiseRejectBlock)reject
131
+ {
132
+ [_cloudStorageCloudKit triggerSync:path withScope:scope withResolver:resolve withRejecter:reject];
133
+ }
134
+
135
+ - (void)deleteFile:(NSString *)path
136
+ scope:(NSString *)scope
137
+ resolve:(RCTPromiseResolveBlock)resolve
138
+ reject:(RCTPromiseRejectBlock)reject
139
+ {
140
+ [_cloudStorageCloudKit deleteFile:path withScope:scope withResolver:resolve withRejecter:reject];
141
+ }
142
+
143
+ - (void)deleteDirectory:(NSString *)path
144
+ recursive:(BOOL)recursive
145
+ scope:(NSString *)scope
146
+ resolve:(RCTPromiseResolveBlock)resolve
147
+ reject:(RCTPromiseRejectBlock)reject
148
+ {
149
+ [_cloudStorageCloudKit
150
+ deleteDirectory:path
151
+ withRecursive:recursive
152
+ withScope:scope
153
+ withResolver:resolve
154
+ withRejecter:reject];
155
+ }
156
+
157
+ - (void)statFile:(NSString *)path
158
+ scope:(NSString *)scope
159
+ resolve:(RCTPromiseResolveBlock)resolve
160
+ reject:(RCTPromiseRejectBlock)reject
161
+ {
162
+ [_cloudStorageCloudKit statFile:path withScope:scope withResolver:resolve withRejecter:reject];
163
+ }
164
+
165
+ - (void)downloadFile:(NSString *)remotePath
166
+ localPath:(NSString *)localPath
167
+ scope:(NSString *)scope
168
+ resolve:(RCTPromiseResolveBlock)resolve
169
+ reject:(RCTPromiseRejectBlock)reject
170
+ {
171
+ [_cloudStorageCloudKit
172
+ downloadFile:remotePath
173
+ withLocalPath:localPath
174
+ withScope:scope
175
+ withResolver:resolve
176
+ withRejecter:reject];
177
+ }
178
+
179
+ - (void)uploadFile:(NSString *)remotePath
180
+ localPath:(NSString *)localPath
181
+ mimeType:(NSString *)mimeType
182
+ scope:(NSString *)scope
183
+ overwrite:(BOOL)overwrite
184
+ resolve:(RCTPromiseResolveBlock)resolve
185
+ reject:(RCTPromiseRejectBlock)reject
186
+ {
187
+ [_cloudStorageCloudKit
188
+ uploadFile:remotePath
189
+ withLocalPath:localPath
190
+ withMimeType:mimeType
191
+ withScope:scope
192
+ withOverwrite:overwrite
193
+ withResolver:resolve
194
+ withRejecter:reject];
195
+ }
196
+
197
+ - (void)isCloudAvailable:(RCTPromiseResolveBlock)resolve
198
+ reject:(RCTPromiseRejectBlock)reject
199
+ {
200
+ [_cloudStorageCloudKit isCloudAvailable:resolve withRejecter:reject];
201
+ }
202
+
203
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
204
+ (const facebook::react::ObjCTurboModule::InitParams &)params
205
+ {
206
+ return std::make_shared<facebook::react::NativeCloudStorageCloudKitIOSSpecJSI>(params);
207
+ }
208
+
209
+ @end