react-native-stallion 1.1.2 → 2.0.0-alpha.1

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 (209) hide show
  1. package/android/src/main/java/com/stallion/Stallion.java +94 -10
  2. package/android/src/main/java/com/stallion/StallionApiUtil.java +58 -0
  3. package/android/src/main/java/com/stallion/StallionCommonUtil.java +25 -0
  4. package/android/src/main/java/com/stallion/StallionConstants.java +51 -15
  5. package/android/src/main/java/com/stallion/StallionDownloadCallback.java +7 -0
  6. package/android/src/main/java/com/stallion/StallionDownloadManager.java +121 -0
  7. package/android/src/main/java/com/stallion/StallionErrorBoundary.java +28 -4
  8. package/android/src/main/java/com/stallion/StallionEventEmitter.java +144 -0
  9. package/android/src/main/java/com/stallion/StallionFileUtil.java +129 -0
  10. package/android/src/main/java/com/stallion/StallionModule.java +100 -154
  11. package/android/src/main/java/com/stallion/StallionRollbackManager.java +82 -0
  12. package/android/src/main/java/com/stallion/StallionStorage.java +16 -6
  13. package/android/src/main/java/com/stallion/StallionSynManager.java +142 -0
  14. package/ios/main/Stallion-Bridging-Header.h +4 -0
  15. package/ios/main/Stallion.m +7 -5
  16. package/ios/main/Stallion.swift +80 -39
  17. package/ios/main/StallionConstants.swift +52 -10
  18. package/ios/main/StallionDownloader.swift +39 -52
  19. package/ios/main/StallionErrorBoundary.h +1 -1
  20. package/ios/main/StallionErrorBoundary.m +45 -28
  21. package/ios/main/StallionEventEmitter.swift +20 -0
  22. package/ios/main/StallionEventManager.h +21 -0
  23. package/ios/main/StallionEventManager.m +57 -0
  24. package/ios/main/StallionModule.m +107 -23
  25. package/ios/main/StallionObjConstants.h +46 -0
  26. package/ios/main/StallionObjConstants.m +124 -0
  27. package/ios/main/StallionObjUtil.h +14 -0
  28. package/ios/main/StallionObjUtil.m +22 -0
  29. package/ios/main/StallionRollbackHandler.h +22 -0
  30. package/ios/main/StallionRollbackHandler.m +128 -0
  31. package/ios/main/StallionSyncManager.swift +149 -0
  32. package/ios/main/StallionUtil.swift +2 -12
  33. package/package.json +6 -2
  34. package/src/index.js +5 -15
  35. package/src/index.js.map +1 -1
  36. package/src/main/components/common/ButtonFullWidth/styles.js +2 -2
  37. package/src/main/components/common/ButtonFullWidth/styles.js.map +1 -1
  38. package/src/main/components/common/Footer/index.js +24 -31
  39. package/src/main/components/common/Footer/index.js.map +1 -1
  40. package/src/main/components/common/Footer/styles.js +34 -33
  41. package/src/main/components/common/Footer/styles.js.map +1 -1
  42. package/src/main/components/common/Header/index.js +12 -8
  43. package/src/main/components/common/Header/index.js.map +1 -1
  44. package/src/main/components/common/Header/styles.js +10 -5
  45. package/src/main/components/common/Header/styles.js.map +1 -1
  46. package/src/main/components/common/ProfileOverlay/index.js +18 -7
  47. package/src/main/components/common/ProfileOverlay/index.js.map +1 -1
  48. package/src/main/components/common/ProfileOverlay/styles.js +41 -8
  49. package/src/main/components/common/ProfileOverlay/styles.js.map +1 -1
  50. package/src/main/components/common/Spinner/index.js +3 -1
  51. package/src/main/components/common/Spinner/index.js.map +1 -1
  52. package/src/main/components/modules/listing/components/BucketCard.js +3 -3
  53. package/src/main/components/modules/listing/components/BucketCard.js.map +1 -1
  54. package/src/main/components/modules/listing/components/BundleCard.js +9 -5
  55. package/src/main/components/modules/listing/components/BundleCard.js.map +1 -1
  56. package/src/main/components/modules/listing/components/BundleCardInfoSection.js +20 -12
  57. package/src/main/components/modules/listing/components/BundleCardInfoSection.js.map +1 -1
  58. package/src/main/components/modules/listing/components/CardDescriptionContent.js +3 -2
  59. package/src/main/components/modules/listing/components/CardDescriptionContent.js.map +1 -1
  60. package/src/main/components/modules/listing/components/MetaCard.js +38 -0
  61. package/src/main/components/modules/listing/components/MetaCard.js.map +1 -0
  62. package/src/main/components/modules/listing/components/SlotView.js +82 -0
  63. package/src/main/components/modules/listing/components/SlotView.js.map +1 -0
  64. package/src/main/components/modules/listing/components/styles/index.js +28 -9
  65. package/src/main/components/modules/listing/components/styles/index.js.map +1 -1
  66. package/src/main/components/modules/listing/hooks/useListing.js +9 -2
  67. package/src/main/components/modules/listing/hooks/useListing.js.map +1 -1
  68. package/src/main/components/modules/listing/index.js +12 -4
  69. package/src/main/components/modules/listing/index.js.map +1 -1
  70. package/src/main/components/modules/login/components/styles/index.js +4 -4
  71. package/src/main/components/modules/login/components/styles/index.js.map +1 -1
  72. package/src/main/components/modules/login/index.js +1 -1
  73. package/src/main/components/modules/login/index.js.map +1 -1
  74. package/src/main/components/modules/login/styles/index.js +7 -6
  75. package/src/main/components/modules/login/styles/index.js.map +1 -1
  76. package/src/main/components/modules/modal/StallionModal.js +13 -11
  77. package/src/main/components/modules/modal/StallionModal.js.map +1 -1
  78. package/src/main/components/modules/modal/hooks/useStallionModal.js +87 -24
  79. package/src/main/components/modules/modal/hooks/useStallionModal.js.map +1 -1
  80. package/src/main/components/modules/prod/index.js +3 -0
  81. package/src/main/components/modules/prod/index.js.map +1 -0
  82. package/src/main/components/modules/prod/prod.js +35 -0
  83. package/src/main/components/modules/prod/prod.js.map +1 -0
  84. package/src/main/components/modules/prod/styles/index.js +20 -0
  85. package/src/main/components/modules/prod/styles/index.js.map +1 -0
  86. package/src/main/constants/apiConstants.js +3 -1
  87. package/src/main/constants/apiConstants.js.map +1 -1
  88. package/src/main/constants/appConstants.js +40 -4
  89. package/src/main/constants/appConstants.js.map +1 -1
  90. package/src/main/constants/colors.js +8 -6
  91. package/src/main/constants/colors.js.map +1 -1
  92. package/src/main/state/actionCreators/useDownloadActions.js +17 -37
  93. package/src/main/state/actionCreators/useDownloadActions.js.map +1 -1
  94. package/src/main/state/actionCreators/useMetaActions.js +4 -5
  95. package/src/main/state/actionCreators/useMetaActions.js.map +1 -1
  96. package/src/main/state/actionCreators/useUpdateMetaActions.js +100 -0
  97. package/src/main/state/actionCreators/useUpdateMetaActions.js.map +1 -0
  98. package/src/main/state/actionCreators/useUserActions.js +4 -4
  99. package/src/main/state/actionCreators/useUserActions.js.map +1 -1
  100. package/src/main/state/index.js +15 -2
  101. package/src/main/state/index.js.map +1 -1
  102. package/src/main/state/reducers/updateMetaReducer.js +36 -0
  103. package/src/main/state/reducers/updateMetaReducer.js.map +1 -0
  104. package/src/main/utils/ErrorBoundary.js +15 -14
  105. package/src/main/utils/ErrorBoundary.js.map +1 -1
  106. package/src/main/utils/EventUtil.js +28 -0
  107. package/src/main/utils/EventUtil.js.map +1 -0
  108. package/src/main/utils/SharedDataManager.js +15 -12
  109. package/src/main/utils/SharedDataManager.js.map +1 -1
  110. package/src/main/utils/StallionEventEmitter.js +20 -0
  111. package/src/main/utils/StallionEventEmitter.js.map +1 -0
  112. package/src/main/utils/StallionNativeUtils.js +60 -0
  113. package/src/main/utils/StallionNativeUtils.js.map +1 -0
  114. package/src/main/utils/apiUtils.js +8 -0
  115. package/src/main/utils/apiUtils.js.map +1 -1
  116. package/src/main/utils/useStallionModal.js +4 -3
  117. package/src/main/utils/useStallionModal.js.map +1 -1
  118. package/src/main/utils/useStallionUpdate.js +13 -0
  119. package/src/main/utils/useStallionUpdate.js.map +1 -0
  120. package/src/main/utils/withStallion.js +1 -4
  121. package/src/main/utils/withStallion.js.map +1 -1
  122. package/src/types/meta.types.js +13 -0
  123. package/src/types/meta.types.js.map +1 -1
  124. package/src/types/updateMeta.types.js +7 -0
  125. package/src/types/updateMeta.types.js.map +1 -0
  126. package/types/index.d.ts +3 -0
  127. package/types/index.d.ts.map +1 -1
  128. package/types/main/components/common/Footer/index.d.ts +1 -4
  129. package/types/main/components/common/Footer/index.d.ts.map +1 -1
  130. package/types/main/components/common/Footer/styles.d.ts +30 -29
  131. package/types/main/components/common/Footer/styles.d.ts.map +1 -1
  132. package/types/main/components/common/Header/index.d.ts.map +1 -1
  133. package/types/main/components/common/Header/styles.d.ts +6 -1
  134. package/types/main/components/common/Header/styles.d.ts.map +1 -1
  135. package/types/main/components/common/ProfileOverlay/index.d.ts.map +1 -1
  136. package/types/main/components/common/ProfileOverlay/styles.d.ts +38 -5
  137. package/types/main/components/common/ProfileOverlay/styles.d.ts.map +1 -1
  138. package/types/main/components/common/Spinner/index.d.ts.map +1 -1
  139. package/types/main/components/modules/listing/components/BucketCard.d.ts.map +1 -1
  140. package/types/main/components/modules/listing/components/BundleCard.d.ts.map +1 -1
  141. package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts +2 -0
  142. package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts.map +1 -1
  143. package/types/main/components/modules/listing/components/CardDescriptionContent.d.ts.map +1 -1
  144. package/types/main/components/modules/listing/components/MetaCard.d.ts +8 -0
  145. package/types/main/components/modules/listing/components/MetaCard.d.ts.map +1 -0
  146. package/types/main/components/modules/listing/components/SlotView.d.ts +5 -0
  147. package/types/main/components/modules/listing/components/SlotView.d.ts.map +1 -0
  148. package/types/main/components/modules/listing/components/styles/index.d.ts +24 -5
  149. package/types/main/components/modules/listing/components/styles/index.d.ts.map +1 -1
  150. package/types/main/components/modules/listing/hooks/useListing.d.ts +2 -0
  151. package/types/main/components/modules/listing/hooks/useListing.d.ts.map +1 -1
  152. package/types/main/components/modules/listing/index.d.ts.map +1 -1
  153. package/types/main/components/modules/login/components/styles/index.d.ts +1 -1
  154. package/types/main/components/modules/login/styles/index.d.ts +4 -3
  155. package/types/main/components/modules/login/styles/index.d.ts.map +1 -1
  156. package/types/main/components/modules/modal/StallionModal.d.ts.map +1 -1
  157. package/types/main/components/modules/modal/hooks/useStallionModal.d.ts +2 -5
  158. package/types/main/components/modules/modal/hooks/useStallionModal.d.ts.map +1 -1
  159. package/types/main/components/modules/prod/index.d.ts +3 -0
  160. package/types/main/components/modules/prod/index.d.ts.map +1 -0
  161. package/types/main/components/modules/prod/prod.d.ts +4 -0
  162. package/types/main/components/modules/prod/prod.d.ts.map +1 -0
  163. package/types/main/components/modules/prod/styles/index.d.ts +16 -0
  164. package/types/main/components/modules/prod/styles/index.d.ts.map +1 -0
  165. package/types/main/constants/apiConstants.d.ts +4 -2
  166. package/types/main/constants/apiConstants.d.ts.map +1 -1
  167. package/types/main/constants/appConstants.d.ts +37 -4
  168. package/types/main/constants/appConstants.d.ts.map +1 -1
  169. package/types/main/constants/colors.d.ts +2 -0
  170. package/types/main/constants/colors.d.ts.map +1 -1
  171. package/types/main/index.d.ts +1 -1
  172. package/types/main/state/actionCreators/useDownloadActions.d.ts +3 -1
  173. package/types/main/state/actionCreators/useDownloadActions.d.ts.map +1 -1
  174. package/types/main/state/actionCreators/useMetaActions.d.ts +1 -1
  175. package/types/main/state/actionCreators/useMetaActions.d.ts.map +1 -1
  176. package/types/main/state/actionCreators/useUpdateMetaActions.d.ts +7 -0
  177. package/types/main/state/actionCreators/useUpdateMetaActions.d.ts.map +1 -0
  178. package/types/main/state/index.d.ts.map +1 -1
  179. package/types/main/state/reducers/updateMetaReducer.d.ts +9 -0
  180. package/types/main/state/reducers/updateMetaReducer.d.ts.map +1 -0
  181. package/types/main/utils/ErrorBoundary.d.ts +1 -1
  182. package/types/main/utils/ErrorBoundary.d.ts.map +1 -1
  183. package/types/main/utils/EventUtil.d.ts +9 -0
  184. package/types/main/utils/EventUtil.d.ts.map +1 -0
  185. package/types/main/utils/SharedDataManager.d.ts +8 -6
  186. package/types/main/utils/SharedDataManager.d.ts.map +1 -1
  187. package/types/main/utils/StallionEventEmitter.d.ts +14 -0
  188. package/types/main/utils/StallionEventEmitter.d.ts.map +1 -0
  189. package/types/main/utils/StallionNativeUtils.d.ts +15 -0
  190. package/types/main/utils/StallionNativeUtils.d.ts.map +1 -0
  191. package/types/main/utils/apiUtils.d.ts +5 -0
  192. package/types/main/utils/apiUtils.d.ts.map +1 -1
  193. package/types/main/utils/useStallionUpdate.d.ts +3 -0
  194. package/types/main/utils/useStallionUpdate.d.ts.map +1 -0
  195. package/types/main/utils/withStallion.d.ts +1 -2
  196. package/types/main/utils/withStallion.d.ts.map +1 -1
  197. package/types/types/globalProvider.types.d.ts +5 -1
  198. package/types/types/globalProvider.types.d.ts.map +1 -1
  199. package/types/types/meta.types.d.ts +19 -3
  200. package/types/types/meta.types.d.ts.map +1 -1
  201. package/types/types/updateMeta.types.d.ts +35 -0
  202. package/types/types/updateMeta.types.d.ts.map +1 -0
  203. package/types/types/utils.types.d.ts +9 -7
  204. package/types/types/utils.types.d.ts.map +1 -1
  205. package/android/src/main/java/com/stallion/StallionZip.java +0 -127
  206. package/src/main/utils/StallionNaitveUtils.js +0 -7
  207. package/src/main/utils/StallionNaitveUtils.js.map +0 -1
  208. package/types/main/utils/StallionNaitveUtils.d.ts +0 -7
  209. package/types/main/utils/StallionNaitveUtils.d.ts.map +0 -1
@@ -0,0 +1,129 @@
1
+ package com.stallion;
2
+
3
+ import android.os.Build;
4
+
5
+ import java.io.BufferedOutputStream;
6
+ import java.io.File;
7
+ import java.io.FileOutputStream;
8
+ import java.io.IOException;
9
+ import java.io.InputStream;
10
+ import java.io.OutputStream;
11
+ import java.nio.charset.Charset;
12
+ import java.util.Enumeration;
13
+ import java.util.zip.ZipEntry;
14
+ import java.util.zip.ZipFile;
15
+
16
+ public class StallionFileUtil {
17
+ private static final int BUF_SIZE = 0x1000;
18
+
19
+ public static void unzipFile(final String zipFilePath, final String destDirectory) {
20
+
21
+ try {
22
+ if (!new File(zipFilePath).exists()) {
23
+ throw new IllegalArgumentException("File does not exist");
24
+ }
25
+ } catch (NullPointerException e) {
26
+ throw new RuntimeException(e);
27
+ }
28
+
29
+ try {
30
+ String charset = "UTF-8";
31
+
32
+ File destDir = new File(destDirectory);
33
+ if (!destDir.exists()) {
34
+ destDir.mkdirs();
35
+ }
36
+
37
+ ZipFile zipFile;
38
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
39
+ zipFile = new ZipFile(zipFilePath, Charset.forName(charset));
40
+ } else {
41
+ zipFile = new ZipFile(zipFilePath);
42
+ }
43
+
44
+ final Enumeration<? extends ZipEntry> entries = zipFile.entries();
45
+ while (entries.hasMoreElements()) {
46
+ final ZipEntry entry = entries.nextElement();
47
+ if (entry.isDirectory()) continue;
48
+
49
+ File fout = new File(destDirectory, entry.getName());
50
+ String canonicalPath = fout.getCanonicalPath();
51
+ String destDirCanonicalPath = new File(destDirectory).getCanonicalPath() + File.separator;
52
+
53
+ if (!canonicalPath.startsWith(destDirCanonicalPath)) {
54
+ throw new SecurityException(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath));
55
+ }
56
+
57
+ if (!fout.exists()) {
58
+ (new File(fout.getParent())).mkdirs();
59
+ }
60
+
61
+ InputStream in = null;
62
+ BufferedOutputStream bout = null;
63
+ try {
64
+ in = zipFile.getInputStream(entry);
65
+ bout = new BufferedOutputStream(new FileOutputStream(fout));
66
+ copy(in, bout);
67
+ bout.close();
68
+ in.close();
69
+ } catch (IOException ex) {
70
+ if (in != null) {
71
+ try {
72
+ in.close();
73
+ } catch (Exception ignored) {
74
+ }
75
+ }
76
+ if (bout != null) {
77
+ try {
78
+ bout.close();
79
+ } catch (Exception ignored) {
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ zipFile.close();
86
+ } catch (Exception ex) {
87
+ throw new RuntimeException(ex);
88
+ }
89
+ }
90
+
91
+
92
+ private static long copy(InputStream from, OutputStream to) throws IOException {
93
+ byte[] buf = new byte[BUF_SIZE];
94
+ long total = 0;
95
+ while (true) {
96
+ int r = from.read(buf);
97
+ if (r == -1) {
98
+ break;
99
+ }
100
+ to.write(buf, 0, r);
101
+ total += r;
102
+ }
103
+ return total;
104
+ }
105
+
106
+ public static void deleteFileOrFolderSilently(File file) {
107
+ if (file.isDirectory()) {
108
+ File[] files = file.listFiles();
109
+ assert files != null;
110
+ for (File fileEntry : files) {
111
+ if (fileEntry.isDirectory()) {
112
+ deleteFileOrFolderSilently(fileEntry);
113
+ } else {
114
+ fileEntry.delete();
115
+ }
116
+ }
117
+ }
118
+ if(!file.delete()) {
119
+ throw new RuntimeException("StallionException: Error deleting file");
120
+ }
121
+ }
122
+ public static void moveFile(File fromFile, File toFile) {
123
+ if(toFile.exists()) {
124
+ deleteFileOrFolderSilently(toFile);
125
+ }
126
+ toFile.getParentFile().mkdirs();
127
+ fromFile.renameTo(toFile);
128
+ }
129
+ }
@@ -1,9 +1,12 @@
1
1
  package com.stallion;
2
2
 
3
+ import android.content.res.Resources;
4
+
3
5
  import androidx.annotation.NonNull;
4
6
 
5
7
  import com.facebook.react.bridge.Arguments;
6
8
  import com.facebook.react.bridge.Callback;
9
+ import com.facebook.react.bridge.LifecycleEventListener;
7
10
  import com.facebook.react.bridge.Promise;
8
11
  import com.facebook.react.bridge.ReactApplicationContext;
9
12
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
@@ -13,36 +16,37 @@ import com.facebook.react.bridge.WritableMap;
13
16
  import com.facebook.react.module.annotations.ReactModule;
14
17
  import com.facebook.react.modules.core.DeviceEventManagerModule;
15
18
 
16
- import android.util.Log;
17
-
18
- import java.io.BufferedInputStream;
19
- import java.io.BufferedOutputStream;
20
- import java.io.File;
21
- import java.io.FileOutputStream;
22
- import java.io.IOException;
23
- import java.net.HttpURLConnection;
24
- import java.net.URL;
25
- import java.nio.ByteBuffer;
26
- import java.util.concurrent.ExecutorService;
27
- import java.util.concurrent.Executors;
28
-
29
19
  @ReactModule(name = StallionConstants.MODULE_NAME)
30
- public class StallionModule extends ReactContextBaseJavaModule {
31
- private ReactApplicationContext currentReactContext;
32
- private String baseDir;
33
- private StallionStorage stallionStorage;
20
+ public class StallionModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
21
+ private final ReactApplicationContext currentReactContext;
22
+ private final StallionStorage stallionStorage;
34
23
  private DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter;
35
24
 
36
25
  public StallionModule(ReactApplicationContext reactContext) {
37
26
  super(reactContext);
38
27
  this.currentReactContext = reactContext;
39
- this.baseDir = reactContext.getFilesDir().getAbsolutePath() + StallionConstants.STALLION_PACKAGE_PATH;
40
28
  StallionStorage.getInstance().Initialize(reactContext);
41
29
  this.stallionStorage = StallionStorage.getInstance();
42
30
  StallionErrorBoundary.initErrorBoundary(reactContext);
43
- String switchState = this.stallionStorage.get(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER);
44
- Boolean isStallionEnabled = switchState == null ? false : switchState.equals(StallionConstants.STALLION_SWITCH_ON);
45
- StallionErrorBoundary.toggleExceptionHandler(isStallionEnabled);
31
+ StallionErrorBoundary.toggleExceptionHandler(true);
32
+ reactContext.addLifecycleEventListener(this);
33
+ }
34
+
35
+ @Override
36
+ public void onHostResume() {
37
+ StallionSynManager.sync();
38
+ }
39
+
40
+ @Override
41
+ public void onHostPause() {}
42
+
43
+ @Override
44
+ public void onHostDestroy() {}
45
+
46
+ @Override
47
+ public void onCatalystInstanceDestroy() {
48
+ super.onCatalystInstanceDestroy();
49
+ this.currentReactContext.removeLifecycleEventListener(this);
46
50
  }
47
51
 
48
52
  @Override
@@ -52,160 +56,102 @@ public class StallionModule extends ReactContextBaseJavaModule {
52
56
  }
53
57
 
54
58
  @ReactMethod
55
- public void setApiKey(String apiKey) {
56
- this.stallionStorage.set(StallionConstants.API_KEY_IDENTIFIER, apiKey);
59
+ public void setStorage(String key, String value) {
60
+ this.stallionStorage.set(key, value);
57
61
  }
58
62
 
63
+
59
64
  @ReactMethod
60
- public void getApiKey(Callback callback) {
61
- callback.invoke(
62
- this.stallionStorage.get(StallionConstants.API_KEY_IDENTIFIER)
63
- );
65
+ public void getStorage(String key, Callback callback) {
66
+ callback.invoke(this.stallionStorage.get(key));
64
67
  }
65
68
 
66
69
  @ReactMethod
67
- public void getStallionMeta(Callback callback) {
68
- WritableMap bundleMeta = Arguments.createMap();
69
- String activeBucket = this.stallionStorage.get(StallionConstants.ACTIVE_BUCKET_IDENTIFIER);
70
- String switchState = this.stallionStorage.get(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER);
71
- int activeVersion = this.stallionStorage.getInt(StallionConstants.ACTIVE_VERSION_IDENTIFIER);
72
-
73
- bundleMeta.putString(StallionConstants.ACTIVE_BUCKET_IDENTIFIER, activeBucket);
74
- bundleMeta.putBoolean(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER,
75
- switchState == null ? false : switchState.equals(StallionConstants.STALLION_SWITCH_ON)
76
- );
77
- bundleMeta.putString(StallionConstants.ACTIVE_VERSION_IDENTIFIER, String.valueOf(activeVersion));
78
- callback.invoke(bundleMeta);
70
+ public void onLaunch(String launchData) {
71
+ StallionStorage.getInstance().setIsMounted();
72
+ StallionEventEmitter.triggerPendingEvents();
73
+ }
74
+
75
+ @ReactMethod
76
+ public void getUniqueId(Callback callback) {
77
+ callback.invoke(StallionCommonUtil.getUniqueId());
78
+ }
79
+
80
+ @ReactMethod
81
+ public void getProjectId(Callback callback) {
82
+ Resources res = currentReactContext.getResources();
83
+ String parentPackageName= currentReactContext.getPackageName();
84
+ int stallionProjectIdRes = res.getIdentifier(StallionConstants.STALLION_PROJECT_ID_IDENTIFIER, "string", parentPackageName);
85
+ String projectId = currentReactContext.getString(stallionProjectIdRes);
86
+ callback.invoke(projectId);
79
87
  }
80
88
 
81
89
  @ReactMethod
82
- public void toggleStallionSwitch(Boolean stallionBundleIsOn) {
83
- this.stallionStorage.set(StallionConstants.STALLION_SWITCH_STATE_IDENTIFIER, stallionBundleIsOn ? StallionConstants.STALLION_SWITCH_ON : StallionConstants.STALLION_SWITCH_OFF);
90
+ public void getAppToken(Callback callback) {
91
+ Resources res = currentReactContext.getResources();
92
+ String parentPackageName= currentReactContext.getPackageName();
93
+ int stallionAppTokenRes = res.getIdentifier(StallionConstants.STALLION_APP_TOKEN_IDENTIFIER, "string", parentPackageName);
94
+ String appToken = currentReactContext.getString(stallionAppTokenRes);
95
+ callback.invoke(appToken);
84
96
  }
85
97
 
86
- private DeviceEventManagerModule.RCTDeviceEventEmitter getEventEmitter() {
87
- if(this.eventEmitter == null) {
88
- this.eventEmitter = this.currentReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
89
- }
90
- return this.eventEmitter;
98
+ @ReactMethod
99
+ public void sync() {
100
+ StallionSynManager.sync();
91
101
  }
92
102
 
93
103
  @ReactMethod
94
104
  public void downloadPackage(ReadableMap bundleInfo, Promise promise) {
95
- String receivedBucketId = bundleInfo.getString("bucketId");
96
105
  String receivedDownloadUrl = bundleInfo.getString("url");
97
- Integer receivedVersion = bundleInfo.getInt("version");
98
-
99
- ExecutorService executor = Executors.newSingleThreadExecutor();
100
-
101
- executor.execute(() -> {
102
- DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter = getEventEmitter();
103
-
104
- FileOutputStream fout = null;
105
- BufferedOutputStream bout = null;
106
- BufferedInputStream inputStream = null;
107
- HttpURLConnection connection = null;
108
- File downloadedZip = null;
109
- boolean isZip = false;
110
-
111
- try {
112
- int DOWNLOAD_BUFFER_SIZE = StallionConstants.DOWNLOAD_BUFFER_SIZE;
113
- URL url = new URL(receivedDownloadUrl);
114
- connection = (HttpURLConnection) url.openConnection();
115
- connection.setRequestMethod( "GET" );
116
- connection.setRequestProperty("x-sdk-access-token", stallionStorage.get(StallionConstants.API_KEY_IDENTIFIER));
117
- connection.setRequestProperty("Content-Type", "application/json");
118
-
119
- connection.setDoInput(true);
120
-
121
- connection.connect();
122
- inputStream = new BufferedInputStream(connection.getInputStream());
123
- File downloadFolder = new File(baseDir + StallionConstants.DOWNLOAD_FOLDER_DIR);
124
- downloadFolder.getParentFile().mkdirs();
125
-
126
- downloadedZip = new File(downloadFolder, StallionConstants.ZIP_FILE_NAME);
127
- downloadedZip.getParentFile().mkdirs();
128
-
129
- fout = new FileOutputStream(downloadedZip, false);
130
- bout = new BufferedOutputStream(fout, DOWNLOAD_BUFFER_SIZE);
131
- byte[] data = new byte[DOWNLOAD_BUFFER_SIZE];
132
- byte[] header = new byte[4];
133
-
134
- long totalBytes = connection.getContentLength();
135
- long receivedBytes = 0;
136
- int numBytesRead;
137
- double prevDownloadFraction = 0;
138
- double progressEventThreshold = 0.1;
139
- while ((numBytesRead = inputStream.read(data, 0, DOWNLOAD_BUFFER_SIZE)) >= 0) {
140
- if (receivedBytes < 4) {
141
- for (int i = 0; i < numBytesRead; i++) {
142
- int headerOffset = (int) (receivedBytes) + i;
143
- if (headerOffset >= 4) {
144
- break;
145
- }
146
- header[headerOffset] = data[i];
147
- }
148
- }
149
-
150
- receivedBytes += numBytesRead;
151
- bout.write(data, 0, numBytesRead);
152
- double currentDownloadFraction = (double) receivedBytes / (double) totalBytes;
153
- if(currentDownloadFraction - prevDownloadFraction > progressEventThreshold) {
154
- prevDownloadFraction = currentDownloadFraction;
155
- getReactApplicationContext().runOnUiQueueThread(() -> getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(StallionConstants.DOWNLOAD_PROGRESS_EVENT, currentDownloadFraction));
156
- }
106
+ String receivedHash = bundleInfo.getString("hash");
107
+ String sdkToken = stallionStorage.get(StallionConstants.STALLION_SDK_TOKEN_KEY);
108
+ StallionDownloadManager.downloadBundle(
109
+ receivedDownloadUrl,
110
+ this.currentReactContext.getFilesDir().getAbsolutePath() + StallionConstants.STAGE_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT,
111
+ sdkToken,
112
+ "",
113
+ new StallionDownloadCallback() {
114
+ @Override
115
+ public void onReject(String prefix, String error) {
116
+ WritableMap errorEventPayload = Arguments.createMap();
117
+ errorEventPayload.putString("releaseHash", receivedHash);
118
+ StallionEventEmitter.sendEvent(
119
+ StallionEventEmitter.getEventPayload(
120
+ StallionConstants.NativeEventTypesStage.DOWNLOAD_ERROR_STAGE.toString(),
121
+ errorEventPayload
122
+ )
123
+ );
124
+ promise.reject(prefix, error);
157
125
  }
158
126
 
159
- isZip = ByteBuffer.wrap(header).getInt() == 0x504b0304;
160
- Log.d("", String.valueOf(isZip));
161
-
162
- } catch (Exception e) {
163
- promise.reject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_API_ERROR_MESSAGE);
164
- } finally {
165
- try {
166
- if (bout != null) bout.close();
167
- if (fout != null) fout.close();
168
- if (inputStream != null) inputStream.close();
169
- if (connection != null) connection.disconnect();
170
- } catch (IOException e) {
171
- promise.reject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_API_ERROR_MESSAGE);
127
+ @Override
128
+ public void onSuccess(String successPayload) {
129
+ stallionStorage.set(StallionConstants.CURRENT_STAGE_SLOT_KEY, StallionConstants.TEMP_FOLDER_SLOT);
130
+ stallionStorage.set(StallionConstants.STAGE_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT, receivedHash);
131
+ WritableMap successEventPayload = Arguments.createMap();
132
+ successEventPayload.putString("releaseHash", receivedHash);
133
+ StallionEventEmitter.sendEvent(
134
+ StallionEventEmitter.getEventPayload(
135
+ StallionConstants.NativeEventTypesStage.DOWNLOAD_COMPLETE_STAGE.toString(),
136
+ successEventPayload
137
+ )
138
+ );
139
+ promise.resolve(StallionConstants.DOWNLOAD_SUCCESS_MESSAGE);
172
140
  }
173
- }
174
-
175
- if (!isZip) {
176
- promise.reject(StallionConstants.DOWNLOAD_ERROR_PREFIX, "Not a zip file");
177
- return;
178
- }
179
141
 
180
- try {
181
- int currentActiveSlot = stallionStorage.getInt(StallionConstants.ACTIVE_SLOT_IDENTIFIER);
182
- int targetSlot;
183
- if(currentActiveSlot == 1) {
184
- targetSlot = 2;
185
- } else if(currentActiveSlot == 2) {
186
- targetSlot = 1;
187
- } else {
188
- targetSlot = 1;
142
+ @Override
143
+ public void onProgress(double downloadFraction) {
144
+ WritableMap progressEventPayload = Arguments.createMap();
145
+ progressEventPayload.putString("releaseHash", receivedHash);
146
+ progressEventPayload.putDouble("progress", downloadFraction);
147
+ StallionEventEmitter.sendEvent(
148
+ StallionEventEmitter.getEventPayload(
149
+ StallionConstants.NativeEventTypesStage.DOWNLOAD_PROGRESS_STAGE.toString(),
150
+ progressEventPayload
151
+ )
152
+ );
189
153
  }
190
- StallionZip.unzipFile(downloadedZip.getAbsolutePath(), baseDir + StallionConstants.BUNDLE_DEST_FOLDER_DIR + StallionConstants.SLOT_FOLDER_DIR + targetSlot);
191
- // setting active bucket ID, slot and version after downloading and all other jobs done
192
- stallionStorage.setInt(StallionConstants.ACTIVE_SLOT_IDENTIFIER, targetSlot);
193
- stallionStorage.set(StallionConstants.ACTIVE_BUCKET_IDENTIFIER, receivedBucketId);
194
- if (receivedVersion != null) {
195
- stallionStorage.setInt(StallionConstants.ACTIVE_VERSION_IDENTIFIER, receivedVersion);
196
- }
197
- promise.resolve(StallionConstants.DOWNLOAD_SUCCESS_MESSAGE);
198
- getReactApplicationContext().runOnUiQueueThread(() -> getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(StallionConstants.DOWNLOAD_PROGRESS_EVENT, 1));
199
- } catch (Exception e) {
200
- promise.reject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_FILESYSTEM_ERROR_MESSAGE);
201
- } finally {
202
- try {
203
- StallionZip.deleteFileOrFolderSilently(downloadedZip);
204
- } catch (Exception e) {
205
- promise.reject(StallionConstants.DOWNLOAD_ERROR_PREFIX, StallionConstants.DOWNLOAD_DELETE_ERROR);
206
- }
207
- return;
208
154
  }
209
- });
155
+ );
210
156
  }
211
157
  }
@@ -0,0 +1,82 @@
1
+ package com.stallion;
2
+
3
+ import com.facebook.react.bridge.Arguments;
4
+ import com.facebook.react.bridge.WritableMap;
5
+
6
+ import java.io.File;
7
+
8
+ public class StallionRollbackManager {
9
+ public static void rollbackProd(Boolean isAutoRollback) {
10
+ StallionStorage stallionStorageInstance = StallionStorage.getInstance();
11
+ String currentProdSlot = stallionStorageInstance.get(StallionConstants.CURRENT_PROD_SLOT_KEY);
12
+ String stableReleaseHash = stallionStorageInstance.get(StallionConstants.PROD_DIRECTORY + StallionConstants.STABLE_FOLDER_SLOT);
13
+ switch (currentProdSlot) {
14
+ case StallionConstants.NEW_FOLDER_SLOT:
15
+ String newReleaseHash = stallionStorageInstance.get(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT);
16
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT, "");
17
+ if(stableReleaseHash.isEmpty()) {
18
+ stallionStorageInstance.set(StallionConstants.CURRENT_PROD_SLOT_KEY, StallionConstants.DEFAULT_FOLDER_SLOT);
19
+ } else {
20
+ stallionStorageInstance.set(StallionConstants.CURRENT_PROD_SLOT_KEY, StallionConstants.STABLE_FOLDER_SLOT);
21
+ }
22
+ emitRollbackEvent(isAutoRollback, newReleaseHash);
23
+ break;
24
+ case StallionConstants.STABLE_FOLDER_SLOT:
25
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.STABLE_FOLDER_SLOT, "");
26
+ stallionStorageInstance.set(StallionConstants.CURRENT_PROD_SLOT_KEY, StallionConstants.DEFAULT_FOLDER_SLOT);
27
+ emitRollbackEvent(isAutoRollback, stableReleaseHash);
28
+ break;
29
+ }
30
+ }
31
+
32
+ public static void fallbackProd() {
33
+ StallionStorage stallionStorageInstance = StallionStorage.getInstance();
34
+ stallionStorageInstance.set(StallionConstants.CURRENT_PROD_SLOT_KEY, StallionConstants.DEFAULT_FOLDER_SLOT);
35
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT, "");
36
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.STABLE_FOLDER_SLOT, "");
37
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.TEMP_FOLDER_SLOT, "");
38
+ }
39
+
40
+ private static void emitRollbackEvent(Boolean isAutoRollback, String rolledBackReleaseHash) {
41
+ WritableMap rollbackEventPayload = Arguments.createMap();
42
+ rollbackEventPayload.putString("releaseHash", rolledBackReleaseHash);
43
+ WritableMap rollbackEventObject = StallionEventEmitter.getEventPayload(
44
+ isAutoRollback ? StallionConstants.NativeEventTypesProd.AUTO_ROLLED_BACK_PROD.toString() : StallionConstants.NativeEventTypesProd.ROLLED_BACK_PROD.toString(),
45
+ rollbackEventPayload
46
+ );
47
+ if(isAutoRollback) {
48
+ StallionEventEmitter.cacheEvent(rollbackEventObject);
49
+ StallionStorage stallionStorageInstance = StallionStorage.getInstance();
50
+ stallionStorageInstance.set(StallionConstants.LAST_ROLLED_BACK_RELEASE_HASH_KEY, rolledBackReleaseHash);
51
+ } else {
52
+ StallionEventEmitter.sendEvent(rollbackEventObject);
53
+ }
54
+ }
55
+
56
+ public static void rollbackStage() {
57
+ StallionStorage stallionStorageInstance = StallionStorage.getInstance();
58
+ stallionStorageInstance.set(StallionConstants.CURRENT_STAGE_SLOT_KEY, StallionConstants.DEFAULT_FOLDER_SLOT);
59
+ stallionStorageInstance.set(StallionConstants.STAGE_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT, "");
60
+ }
61
+
62
+ public static void stabilizeRelease() {
63
+ StallionStorage stallionStorageInstance = StallionStorage.getInstance();
64
+
65
+ String baseFolderPath = stallionStorageInstance.mContext.getFilesDir().getAbsolutePath();
66
+ StallionFileUtil.moveFile(
67
+ new File(baseFolderPath, StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT),
68
+ new File(baseFolderPath, StallionConstants.PROD_DIRECTORY + StallionConstants.STABLE_FOLDER_SLOT)
69
+ );
70
+ String newReleaseHash = stallionStorageInstance.get(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT);
71
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.STABLE_FOLDER_SLOT, newReleaseHash);
72
+ stallionStorageInstance.set(StallionConstants.PROD_DIRECTORY + StallionConstants.NEW_FOLDER_SLOT, "");
73
+ WritableMap stabilizeEventPayload = Arguments.createMap();
74
+ stabilizeEventPayload.putString("releaseHash", newReleaseHash);
75
+ StallionEventEmitter.sendEvent(
76
+ StallionEventEmitter.getEventPayload(
77
+ StallionConstants.NativeEventTypesProd.STABILIZED_PROD.toString(),
78
+ stabilizeEventPayload
79
+ )
80
+ );
81
+ }
82
+ }
@@ -6,7 +6,8 @@ import android.preference.PreferenceManager;
6
6
 
7
7
  public class StallionStorage {
8
8
  private static StallionStorage mInstance;
9
- private Context mContext;
9
+ private Boolean isMounted = false;
10
+ public Context mContext;
10
11
 
11
12
  private SharedPreferences sharedPreference;
12
13
 
@@ -15,11 +16,23 @@ public class StallionStorage {
15
16
  return mInstance;
16
17
  }
17
18
 
19
+ public Boolean getIsMounted() {
20
+ return mInstance.isMounted;
21
+ }
22
+
23
+ public void setIsMounted() {
24
+ mInstance.isMounted = true;
25
+ }
26
+
18
27
  public void Initialize(Context context){
19
28
  mContext = context;
20
29
  sharedPreference = PreferenceManager.getDefaultSharedPreferences(mContext);
21
30
  }
22
31
 
32
+ public String get(String key) {
33
+ return sharedPreference.getString(key, "");
34
+ }
35
+
23
36
  public void set(String key, String value) {
24
37
  SharedPreferences.Editor editor = sharedPreference.edit();
25
38
  editor.putString(key, value);
@@ -36,18 +49,15 @@ public class StallionStorage {
36
49
  return sharedPreference.getInt(key, -1);
37
50
  }
38
51
 
39
- public String get(String key) {
40
- return sharedPreference.getString(key, null);
41
- }
42
-
43
52
  public void delete(String key, Boolean deleteAll) {
44
53
  SharedPreferences.Editor editor = sharedPreference.edit();
45
- if(deleteAll == true){
54
+ if(deleteAll){
46
55
  editor.clear();
47
56
  return;
48
57
  } else {
49
58
  editor.remove(key);
50
59
  }
60
+ editor.commit();
51
61
  }
52
62
  }
53
63