react-native-mosquito-transport 0.0.14

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 (86) hide show
  1. package/CODE_OF_CONDUCT.md +133 -0
  2. package/CONTRIBUTING.md +114 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1 -0
  5. package/android/build.gradle +77 -0
  6. package/android/gradle.properties +5 -0
  7. package/android/src/main/AndroidManifest.xml +4 -0
  8. package/android/src/main/java/com/mosquitodb/MosquitodbModule.java +32 -0
  9. package/android/src/main/java/com/mosquitodb/MosquitodbPackage.java +28 -0
  10. package/example/.bundle/config +2 -0
  11. package/example/.node-version +1 -0
  12. package/example/.watchmanconfig +1 -0
  13. package/example/Gemfile +6 -0
  14. package/example/android/app/build.gradle +170 -0
  15. package/example/android/app/debug.keystore +0 -0
  16. package/example/android/app/proguard-rules.pro +10 -0
  17. package/example/android/app/src/debug/AndroidManifest.xml +13 -0
  18. package/example/android/app/src/debug/java/com/mosquitodbexample/ReactNativeFlipper.java +75 -0
  19. package/example/android/app/src/main/AndroidManifest.xml +25 -0
  20. package/example/android/app/src/main/java/com/mosquitodbexample/MainActivity.java +35 -0
  21. package/example/android/app/src/main/java/com/mosquitodbexample/MainApplication.java +62 -0
  22. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +36 -0
  23. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  24. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  25. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  26. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  27. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  28. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  29. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  30. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  31. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  32. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  33. package/example/android/app/src/main/res/values/strings.xml +3 -0
  34. package/example/android/app/src/main/res/values/styles.xml +9 -0
  35. package/example/android/app/src/release/java/com/mosquitodbexample/ReactNativeFlipper.java +20 -0
  36. package/example/android/build.gradle +21 -0
  37. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  38. package/example/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  39. package/example/android/gradle.properties +44 -0
  40. package/example/android/gradlew +234 -0
  41. package/example/android/gradlew.bat +89 -0
  42. package/example/android/settings.gradle +4 -0
  43. package/example/app.json +4 -0
  44. package/example/babel.config.js +17 -0
  45. package/example/index.js +5 -0
  46. package/example/ios/.xcode.env +11 -0
  47. package/example/ios/File.swift +6 -0
  48. package/example/ios/MosquitodbExample/AppDelegate.h +6 -0
  49. package/example/ios/MosquitodbExample/AppDelegate.mm +36 -0
  50. package/example/ios/MosquitodbExample/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  51. package/example/ios/MosquitodbExample/Images.xcassets/Contents.json +6 -0
  52. package/example/ios/MosquitodbExample/Info.plist +55 -0
  53. package/example/ios/MosquitodbExample/LaunchScreen.storyboard +47 -0
  54. package/example/ios/MosquitodbExample/main.m +10 -0
  55. package/example/ios/MosquitodbExample-Bridging-Header.h +3 -0
  56. package/example/ios/MosquitodbExample.xcodeproj/project.pbxproj +702 -0
  57. package/example/ios/MosquitodbExample.xcodeproj/xcshareddata/xcschemes/MosquitodbExample.xcscheme +88 -0
  58. package/example/ios/MosquitodbExampleTests/Info.plist +24 -0
  59. package/example/ios/MosquitodbExampleTests/MosquitodbExampleTests.m +66 -0
  60. package/example/ios/Podfile +60 -0
  61. package/example/metro.config.js +40 -0
  62. package/example/package.json +22 -0
  63. package/example/react-native.config.js +10 -0
  64. package/example/src/App.tsx +31 -0
  65. package/ios/Mosquitodb-Bridging-Header.h +2 -0
  66. package/ios/Mosquitodb.m +22 -0
  67. package/ios/Mosquitodb.swift +305 -0
  68. package/ios/Mosquitodb.xcodeproj/project.pbxproj +283 -0
  69. package/package.json +45 -0
  70. package/react-native-mosquitodb.podspec +35 -0
  71. package/src/helpers/EngineApi.js +34 -0
  72. package/src/helpers/listeners.js +7 -0
  73. package/src/helpers/peripherals.js +195 -0
  74. package/src/helpers/utils.js +113 -0
  75. package/src/helpers/values.js +72 -0
  76. package/src/helpers/variables.js +34 -0
  77. package/src/index.d.ts +373 -0
  78. package/src/index.js +369 -0
  79. package/src/products/auth/accessor.js +151 -0
  80. package/src/products/auth/index.js +279 -0
  81. package/src/products/database/accessor.js +316 -0
  82. package/src/products/database/index.js +603 -0
  83. package/src/products/database/types.js +22 -0
  84. package/src/products/database/validator.js +282 -0
  85. package/src/products/http_callable/index.js +230 -0
  86. package/src/products/storage/index.js +217 -0
@@ -0,0 +1,217 @@
1
+ import EngineApi from "../../helpers/EngineApi";
2
+ import { encodeBinary, prefixStoragePath } from "../../helpers/peripherals";
3
+ import { Scoped } from "../../helpers/variables";
4
+ import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform } from 'react-native';
5
+ import { awaitReachableServer, buildFetchInterface, simplifyError } from "../../helpers/utils";
6
+ import { awaitRefreshToken } from "../auth/accessor";
7
+
8
+ const LINKING_ERROR =
9
+ `The package 'react-native-mosquito-transport' doesn't seem to be linked. Make sure: \n\n` +
10
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
11
+ '- You rebuilt the app after installing the package\n' +
12
+ '- You are not using Expo Go\n';
13
+
14
+ const RNMTModule = NativeModules.Mosquitodb || (
15
+ new Proxy({}, {
16
+ get() {
17
+ throw new Error(LINKING_ERROR);
18
+ },
19
+ })
20
+ ),
21
+ emitter = Platform.OS === 'android' ?
22
+ DeviceEventEmitter : new NativeEventEmitter(RNMTModule);
23
+
24
+ export class MTStorage {
25
+ constructor(config) {
26
+ this.builder = { ...config };
27
+ }
28
+
29
+ downloadFile(link = '', onComplete, destination, onProgress) {
30
+ let hasFinished, isPaused, hasCancelled;
31
+
32
+ const { projectUrl, accessKey, awaitStorage } = this.builder;
33
+
34
+ if (destination && (!destination?.trim() || typeof destination !== 'string')) {
35
+ onComplete?.({ error: 'destination_invalid', message: 'destination is invalid in downloadFile()' });
36
+ return () => { };
37
+ }
38
+ if (destination) destination = prefixStoragePath(destination?.trim());
39
+
40
+ if (typeof link !== 'string' || !link.trim().startsWith(`${EngineApi.staticStorage(projectUrl)}/`)) {
41
+ onComplete?.({
42
+ error: 'invalid_link',
43
+ message: `link has an invalid value, expected a string that starts with "${EngineApi.staticStorage(projectUrl)}/"`
44
+ });
45
+ return () => { };
46
+ }
47
+ link = link.trim();
48
+
49
+ const init = async () => {
50
+ if (awaitStorage) await awaitReachableServer(projectUrl);
51
+ await awaitRefreshToken(projectUrl);
52
+
53
+ if (hasCancelled) return;
54
+
55
+ const processID = `${++Scoped.StorageProcessID}`,
56
+ progressListener = emitter.addListener('mt-download-progress', ({ processID: ref, receivedBtyes, expectedBytes }) => {
57
+ if (processID !== ref || hasFinished || hasCancelled) return;
58
+ onProgress?.({
59
+ receivedBtyes,
60
+ expectedBytes,
61
+ isPaused: !!isPaused,
62
+ pause: () => {
63
+ if (hasFinished || isPaused || hasCancelled) return;
64
+ RNMTModule.pauseDownload(processID);
65
+ isPaused = true;
66
+ },
67
+ resume: () => {
68
+ if (hasFinished || !isPaused || hasCancelled) return;
69
+ RNMTModule.pauseDownload(processID);
70
+ isPaused = false;
71
+ }
72
+ });
73
+ }),
74
+ resultListener = emitter.addListener('mt-download-status', ({ processID: ref, error, errorDes, result }) => {
75
+ if (processID !== ref) return;
76
+ if (result)
77
+ try {
78
+ result = JSON.parse(result);
79
+ } catch (e) { }
80
+
81
+ const path = result?.file || undefined;
82
+
83
+ if (!hasFinished && !hasCancelled)
84
+ onComplete?.(path ? undefined : (result?.simpleError || { error, errorDes }), path);
85
+ resultListener.remove();
86
+ progressListener.remove();
87
+ hasFinished = true;
88
+ });
89
+
90
+ RNMTModule.downloadFile({
91
+ url: link,
92
+ authToken: Scoped.AuthJWTToken[projectUrl],
93
+ ...(destination ? {
94
+ destination: destination.substring('file://'.length),
95
+ destinationDir: `${destination.substring('file://'.length)}`.split('/').filter((_, i, a) => i !== a.length - 1).join('/')
96
+ } : {}),
97
+ processID,
98
+ urlName: link.split('/').pop(),
99
+ authorization: `Bearer ${encodeBinary(accessKey)}`
100
+ });
101
+ }
102
+
103
+ init();
104
+
105
+ return () => {
106
+ if (hasFinished || hasCancelled) return;
107
+ RNMTModule.cancelDownload(processID);
108
+ hasCancelled = true;
109
+ setTimeout(() => {
110
+ onComplete?.({ error: 'download_aborted', message: 'The download process was aborted' });
111
+ }, 1);
112
+ }
113
+ }
114
+
115
+ uploadFile(file = '', destination = '', onComplete, onProgress) {
116
+ let hasFinished, hasCancelled;
117
+
118
+ if (!file?.trim() || typeof file !== 'string') {
119
+ onComplete?.({ error: 'file_path_invalid', message: 'file must be a non-empty string in uploadFile()' });
120
+ return () => { };
121
+ }
122
+ destination = destination?.trim();
123
+
124
+ const destErr = validateDestination(destination),
125
+ isAsset = (file.startsWith('ph://') || file.startsWith('content://'));
126
+
127
+ file = isAsset ? file.trim() : prefixStoragePath(file.trim());
128
+
129
+ if (destErr) {
130
+ onComplete?.({ error: 'destination_invalid', message: destErr });
131
+ return () => { };
132
+ }
133
+
134
+ const { projectUrl, accessKey, awaitStorage } = this.builder,
135
+ processID = `${++Scoped.StorageProcessID}`;
136
+
137
+ const init = async () => {
138
+ if (awaitStorage) await awaitReachableServer(projectUrl);
139
+ await awaitRefreshToken(projectUrl);
140
+
141
+ if (hasCancelled) return;
142
+ const progressListener = emitter.addListener('mt-uploading-progress', ({ processID: ref, sentBtyes, totalBytes }) => {
143
+ if (processID !== ref || hasFinished || hasCancelled) return;
144
+ onProgress?.({ sentBtyes, totalBytes });
145
+ }),
146
+ resultListener = emitter.addListener('mt-uploading-status', ({ processID: ref, error, errorDes, result }) => {
147
+ if (processID !== ref || hasFinished) return;
148
+ if (result)
149
+ try {
150
+ result = JSON.parse(result);
151
+ } catch (e) { }
152
+
153
+ const downloadUrl = result?.downloadUrl || undefined;
154
+
155
+ if (!hasFinished && !hasCancelled)
156
+ onComplete?.(downloadUrl ? undefined : (result?.simpleError || { error, errorDes }), downloadUrl);
157
+ resultListener.remove();
158
+ progressListener.remove();
159
+ hasFinished = true;
160
+ });
161
+
162
+ RNMTModule.uploadFile({
163
+ url: EngineApi._uploadFile(projectUrl),
164
+ file: isAsset ? file : file.substring('file://'.length),
165
+ authToken: Scoped.AuthJWTToken[projectUrl],
166
+ destination,
167
+ processID,
168
+ authorization: `Bearer ${encodeBinary(accessKey)}`
169
+ });
170
+ }
171
+
172
+ init();
173
+
174
+ return () => {
175
+ if (hasFinished || hasCancelled) return;
176
+ hasCancelled = true;
177
+ setTimeout(() => {
178
+ onComplete?.({ error: 'upload_aborted', message: 'The upload process was aborted' });
179
+ }, 1);
180
+ RNMTModule.cancelUpload(processID);
181
+ }
182
+ }
183
+
184
+ deleteFile = (path) => deleteContent(this.builder, path);
185
+ deleteFolder = (path) => deleteContent(this.builder, path, true);
186
+ }
187
+
188
+ const deleteContent = async (builder, path, isFolder) => {
189
+ const { projectUrl, accessKey } = builder;
190
+
191
+ try {
192
+ const r = await (await fetch(
193
+ EngineApi[isFolder ? '_deleteFolder' : '_deleteFile'](projectUrl),
194
+ buildFetchInterface({ path }, accessKey, Scoped.AuthJWTToken[projectUrl], 'DELETE')
195
+ )).json();
196
+ if (r.simpleError) throw r;
197
+ if (r.status !== 'success') throw 'operation not successful';
198
+ } catch (e) {
199
+ if (e?.simpleError) throw e.simpleError;
200
+ throw simplifyError('unexpected_error', `${e}`).simpleError;
201
+ }
202
+ }
203
+
204
+ const validateDestination = (t = '') => {
205
+ t = t.trim();
206
+
207
+ if (!t || typeof t !== 'string') return `destination is required`;
208
+ if (t.startsWith('/') || t.endsWith('/')) return 'destination must neither start with "/" nor end with "/"';
209
+ let l = '', r;
210
+
211
+ t.split('').forEach(e => {
212
+ if (e === '/' && l === '/') r = 'invalid destination path, "/" cannot be side by side';
213
+ l = e;
214
+ });
215
+
216
+ return r;
217
+ };