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

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 (296) hide show
  1. package/android/src/main/java/com/stallion/Stallion.java +153 -9
  2. package/android/src/main/java/com/stallion/StallionModule.java +128 -167
  3. package/android/src/main/java/com/stallion/events/StallionEventConstants.java +22 -0
  4. package/android/src/main/java/com/stallion/events/StallionEventManager.java +160 -0
  5. package/android/src/main/java/com/stallion/networkmanager/StallionApiConstants.java +28 -0
  6. package/android/src/main/java/com/stallion/networkmanager/StallionApiManager.java +96 -0
  7. package/android/src/main/java/com/stallion/networkmanager/StallionDownloadCallback.java +7 -0
  8. package/android/src/main/java/com/stallion/networkmanager/StallionFileDownloader.java +224 -0
  9. package/android/src/main/java/com/stallion/networkmanager/StallionStageManager.java +77 -0
  10. package/android/src/main/java/com/stallion/networkmanager/StallionSyncHandler.java +183 -0
  11. package/android/src/main/java/com/stallion/storage/StallionConfig.java +120 -0
  12. package/android/src/main/java/com/stallion/storage/StallionConfigConstants.java +24 -0
  13. package/android/src/main/java/com/stallion/storage/StallionMeta.java +206 -0
  14. package/android/src/main/java/com/stallion/storage/StallionMetaConstants.java +30 -0
  15. package/android/src/main/java/com/stallion/storage/StallionStateManager.java +110 -0
  16. package/android/src/main/java/com/stallion/{StallionDefaultErrorActivity.java → utils/StallionErrorActivity.java} +11 -10
  17. package/android/src/main/java/com/stallion/utils/StallionExceptionHandler.java +102 -0
  18. package/android/src/main/java/com/stallion/utils/StallionFileManager.java +205 -0
  19. package/android/src/main/java/com/stallion/utils/StallionSlotManager.java +110 -0
  20. package/ios/main/Stallion-Bridging-Header.h +6 -1
  21. package/ios/main/Stallion.m +28 -9
  22. package/ios/main/Stallion.swift +132 -50
  23. package/ios/main/StallionConfig.h +24 -0
  24. package/ios/main/StallionConfig.m +62 -0
  25. package/ios/main/StallionConfigConstants.h +32 -0
  26. package/ios/main/StallionConfigConstants.m +32 -0
  27. package/ios/main/StallionConstants.swift +53 -10
  28. package/ios/main/StallionEventHandler.h +23 -0
  29. package/ios/main/StallionEventHandler.m +138 -0
  30. package/ios/main/StallionExceptionHandler.h +18 -0
  31. package/ios/main/StallionExceptionHandler.m +94 -0
  32. package/ios/main/StallionFileDownloader.swift +147 -0
  33. package/ios/main/StallionFileManager.h +20 -0
  34. package/ios/main/StallionFileManager.m +126 -0
  35. package/ios/main/StallionMeta.h +29 -0
  36. package/ios/main/StallionMeta.m +98 -0
  37. package/ios/main/StallionMetaConstants.h +28 -0
  38. package/ios/main/StallionMetaConstants.m +42 -0
  39. package/ios/main/StallionModule.m +137 -20
  40. package/ios/main/StallionObjConstants.h +47 -0
  41. package/ios/main/StallionObjConstants.m +128 -0
  42. package/ios/main/StallionSlotManager.h +21 -0
  43. package/ios/main/StallionSlotManager.m +114 -0
  44. package/ios/main/StallionStageManager.swift +84 -0
  45. package/ios/main/StallionStateManager.h +31 -0
  46. package/ios/main/StallionStateManager.m +87 -0
  47. package/ios/main/StallionSyncHandler.swift +212 -0
  48. package/package.json +6 -2
  49. package/src/index.js +5 -15
  50. package/src/index.js.map +1 -1
  51. package/src/main/components/common/ButtonFullWidth/styles.js +2 -2
  52. package/src/main/components/common/ButtonFullWidth/styles.js.map +1 -1
  53. package/src/main/components/common/Footer/index.js +24 -31
  54. package/src/main/components/common/Footer/index.js.map +1 -1
  55. package/src/main/components/common/Footer/styles.js +34 -33
  56. package/src/main/components/common/Footer/styles.js.map +1 -1
  57. package/src/main/components/common/Header/index.js +14 -17
  58. package/src/main/components/common/Header/index.js.map +1 -1
  59. package/src/main/components/common/Header/styles.js +10 -5
  60. package/src/main/components/common/Header/styles.js.map +1 -1
  61. package/src/main/components/common/Spinner/index.js +3 -1
  62. package/src/main/components/common/Spinner/index.js.map +1 -1
  63. package/src/main/components/modules/listing/components/BucketCard.js +3 -3
  64. package/src/main/components/modules/listing/components/BucketCard.js.map +1 -1
  65. package/src/main/components/modules/listing/components/BundleCard.js +9 -5
  66. package/src/main/components/modules/listing/components/BundleCard.js.map +1 -1
  67. package/src/main/components/modules/listing/components/BundleCardInfoSection.js +21 -12
  68. package/src/main/components/modules/listing/components/BundleCardInfoSection.js.map +1 -1
  69. package/src/main/components/modules/listing/components/CardDescriptionContent.js +3 -2
  70. package/src/main/components/modules/listing/components/CardDescriptionContent.js.map +1 -1
  71. package/src/main/components/modules/listing/components/ConfigView.js +19 -0
  72. package/src/main/components/modules/listing/components/ConfigView.js.map +1 -0
  73. package/src/main/components/modules/listing/components/MetaCard.js +38 -0
  74. package/src/main/components/modules/listing/components/MetaCard.js.map +1 -0
  75. package/src/main/components/modules/listing/components/SlotView.js +84 -0
  76. package/src/main/components/modules/listing/components/SlotView.js.map +1 -0
  77. package/src/main/components/modules/listing/components/styles/index.js +31 -10
  78. package/src/main/components/modules/listing/components/styles/index.js.map +1 -1
  79. package/src/main/components/modules/listing/hooks/useListing.js +5 -4
  80. package/src/main/components/modules/listing/hooks/useListing.js.map +1 -1
  81. package/src/main/components/modules/listing/index.js +12 -4
  82. package/src/main/components/modules/listing/index.js.map +1 -1
  83. package/src/main/components/modules/login/index.js +42 -38
  84. package/src/main/components/modules/login/index.js.map +1 -1
  85. package/src/main/components/modules/login/styles/index.js +21 -7
  86. package/src/main/components/modules/login/styles/index.js.map +1 -1
  87. package/src/main/components/modules/modal/StallionModal.js +28 -31
  88. package/src/main/components/modules/modal/StallionModal.js.map +1 -1
  89. package/src/main/components/modules/modal/hooks/useStallionModal.js +16 -52
  90. package/src/main/components/modules/modal/hooks/useStallionModal.js.map +1 -1
  91. package/src/main/components/modules/prod/index.js +3 -0
  92. package/src/main/components/modules/prod/index.js.map +1 -0
  93. package/src/main/components/modules/prod/prod.js +35 -0
  94. package/src/main/components/modules/prod/prod.js.map +1 -0
  95. package/src/main/components/modules/prod/styles/index.js +23 -0
  96. package/src/main/components/modules/prod/styles/index.js.map +1 -0
  97. package/src/main/constants/apiConstants.js +4 -2
  98. package/src/main/constants/apiConstants.js.map +1 -1
  99. package/src/main/constants/appConstants.js +43 -7
  100. package/src/main/constants/appConstants.js.map +1 -1
  101. package/src/main/constants/colors.js +8 -6
  102. package/src/main/constants/colors.js.map +1 -1
  103. package/src/main/state/actionCreators/useBucketActions.js +10 -13
  104. package/src/main/state/actionCreators/useBucketActions.js.map +1 -1
  105. package/src/main/state/actionCreators/useBundleActions.js +14 -17
  106. package/src/main/state/actionCreators/useBundleActions.js.map +1 -1
  107. package/src/main/state/actionCreators/useConfigActions.js +20 -0
  108. package/src/main/state/actionCreators/useConfigActions.js.map +1 -0
  109. package/src/main/state/actionCreators/useDownloadActions.js +20 -42
  110. package/src/main/state/actionCreators/useDownloadActions.js.map +1 -1
  111. package/src/main/state/actionCreators/useMetaActions.js +6 -5
  112. package/src/main/state/actionCreators/useMetaActions.js.map +1 -1
  113. package/src/main/state/actionCreators/useUpdateMetaActions.js +77 -0
  114. package/src/main/state/actionCreators/useUpdateMetaActions.js.map +1 -0
  115. package/src/main/state/actionCreators/useUserActions.js +25 -85
  116. package/src/main/state/actionCreators/useUserActions.js.map +1 -1
  117. package/src/main/state/actions/configActions.js +8 -0
  118. package/src/main/state/actions/configActions.js.map +1 -0
  119. package/src/main/state/actions/userActions.js +3 -15
  120. package/src/main/state/actions/userActions.js.map +1 -1
  121. package/src/main/state/index.js +30 -13
  122. package/src/main/state/index.js.map +1 -1
  123. package/src/main/state/reducers/configReducer.js +19 -0
  124. package/src/main/state/reducers/configReducer.js.map +1 -0
  125. package/src/main/state/reducers/updateMetaReducer.js +36 -0
  126. package/src/main/state/reducers/updateMetaReducer.js.map +1 -0
  127. package/src/main/state/reducers/userReducer.js +3 -37
  128. package/src/main/state/reducers/userReducer.js.map +1 -1
  129. package/src/main/state/useStallionEvents.js +102 -0
  130. package/src/main/state/useStallionEvents.js.map +1 -0
  131. package/src/main/utils/ErrorBoundary.js +19 -16
  132. package/src/main/utils/ErrorBoundary.js.map +1 -1
  133. package/src/main/utils/StallionEventEmitter.js +20 -0
  134. package/src/main/utils/StallionEventEmitter.js.map +1 -0
  135. package/src/main/utils/StallionNativeUtils.js +35 -0
  136. package/src/main/utils/StallionNativeUtils.js.map +1 -0
  137. package/src/main/utils/debounce.js +16 -0
  138. package/src/main/utils/debounce.js.map +1 -0
  139. package/src/main/utils/useApiClient.js +28 -0
  140. package/src/main/utils/useApiClient.js.map +1 -0
  141. package/src/main/utils/useStallionModal.js +4 -3
  142. package/src/main/utils/useStallionModal.js.map +1 -1
  143. package/src/main/utils/useStallionUpdate.js +14 -0
  144. package/src/main/utils/useStallionUpdate.js.map +1 -0
  145. package/src/main/utils/withStallion.js +1 -4
  146. package/src/main/utils/withStallion.js.map +1 -1
  147. package/src/types/config.types.js +5 -0
  148. package/src/types/config.types.js.map +1 -0
  149. package/src/types/meta.types.js +11 -0
  150. package/src/types/meta.types.js.map +1 -1
  151. package/src/types/updateMeta.types.js +7 -0
  152. package/src/types/updateMeta.types.js.map +1 -0
  153. package/src/types/user.types.js +1 -2
  154. package/src/types/user.types.js.map +1 -1
  155. package/types/index.d.ts +3 -0
  156. package/types/index.d.ts.map +1 -1
  157. package/types/main/components/common/Footer/index.d.ts +1 -4
  158. package/types/main/components/common/Footer/index.d.ts.map +1 -1
  159. package/types/main/components/common/Footer/styles.d.ts +30 -29
  160. package/types/main/components/common/Footer/styles.d.ts.map +1 -1
  161. package/types/main/components/common/Header/index.d.ts +0 -2
  162. package/types/main/components/common/Header/index.d.ts.map +1 -1
  163. package/types/main/components/common/Header/styles.d.ts +6 -1
  164. package/types/main/components/common/Header/styles.d.ts.map +1 -1
  165. package/types/main/components/common/Spinner/index.d.ts.map +1 -1
  166. package/types/main/components/modules/listing/components/BucketCard.d.ts.map +1 -1
  167. package/types/main/components/modules/listing/components/BundleCard.d.ts.map +1 -1
  168. package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts +2 -0
  169. package/types/main/components/modules/listing/components/BundleCardInfoSection.d.ts.map +1 -1
  170. package/types/main/components/modules/listing/components/CardDescriptionContent.d.ts.map +1 -1
  171. package/types/main/components/modules/listing/components/ConfigView.d.ts +8 -0
  172. package/types/main/components/modules/listing/components/ConfigView.d.ts.map +1 -0
  173. package/types/main/components/modules/listing/components/MetaCard.d.ts +8 -0
  174. package/types/main/components/modules/listing/components/MetaCard.d.ts.map +1 -0
  175. package/types/main/components/modules/listing/components/SlotView.d.ts +5 -0
  176. package/types/main/components/modules/listing/components/SlotView.d.ts.map +1 -0
  177. package/types/main/components/modules/listing/components/styles/index.d.ts +26 -5
  178. package/types/main/components/modules/listing/components/styles/index.d.ts.map +1 -1
  179. package/types/main/components/modules/listing/hooks/useListing.d.ts +2 -0
  180. package/types/main/components/modules/listing/hooks/useListing.d.ts.map +1 -1
  181. package/types/main/components/modules/listing/index.d.ts.map +1 -1
  182. package/types/main/components/modules/login/index.d.ts.map +1 -1
  183. package/types/main/components/modules/login/styles/index.d.ts +17 -3
  184. package/types/main/components/modules/login/styles/index.d.ts.map +1 -1
  185. package/types/main/components/modules/modal/StallionModal.d.ts.map +1 -1
  186. package/types/main/components/modules/modal/hooks/useStallionModal.d.ts +2 -11
  187. package/types/main/components/modules/modal/hooks/useStallionModal.d.ts.map +1 -1
  188. package/types/main/components/modules/prod/index.d.ts +3 -0
  189. package/types/main/components/modules/prod/index.d.ts.map +1 -0
  190. package/types/main/components/modules/prod/prod.d.ts +4 -0
  191. package/types/main/components/modules/prod/prod.d.ts.map +1 -0
  192. package/types/main/components/modules/prod/styles/index.d.ts +19 -0
  193. package/types/main/components/modules/prod/styles/index.d.ts.map +1 -0
  194. package/types/main/constants/apiConstants.d.ts +5 -3
  195. package/types/main/constants/apiConstants.d.ts.map +1 -1
  196. package/types/main/constants/appConstants.d.ts +40 -7
  197. package/types/main/constants/appConstants.d.ts.map +1 -1
  198. package/types/main/constants/colors.d.ts +2 -0
  199. package/types/main/constants/colors.d.ts.map +1 -1
  200. package/types/main/index.d.ts +1 -1
  201. package/types/main/state/actionCreators/useBucketActions.d.ts +2 -1
  202. package/types/main/state/actionCreators/useBucketActions.d.ts.map +1 -1
  203. package/types/main/state/actionCreators/useBundleActions.d.ts +2 -1
  204. package/types/main/state/actionCreators/useBundleActions.d.ts.map +1 -1
  205. package/types/main/state/actionCreators/useConfigActions.d.ts +7 -0
  206. package/types/main/state/actionCreators/useConfigActions.d.ts.map +1 -0
  207. package/types/main/state/actionCreators/useDownloadActions.d.ts +5 -2
  208. package/types/main/state/actionCreators/useDownloadActions.d.ts.map +1 -1
  209. package/types/main/state/actionCreators/useMetaActions.d.ts +1 -1
  210. package/types/main/state/actionCreators/useMetaActions.d.ts.map +1 -1
  211. package/types/main/state/actionCreators/useUpdateMetaActions.d.ts +8 -0
  212. package/types/main/state/actionCreators/useUpdateMetaActions.d.ts.map +1 -0
  213. package/types/main/state/actionCreators/useUserActions.d.ts +5 -7
  214. package/types/main/state/actionCreators/useUserActions.d.ts.map +1 -1
  215. package/types/main/state/actions/configActions.d.ts +3 -0
  216. package/types/main/state/actions/configActions.d.ts.map +1 -0
  217. package/types/main/state/actions/userActions.d.ts +2 -4
  218. package/types/main/state/actions/userActions.d.ts.map +1 -1
  219. package/types/main/state/index.d.ts.map +1 -1
  220. package/types/main/state/reducers/configReducer.d.ts +4 -0
  221. package/types/main/state/reducers/configReducer.d.ts.map +1 -0
  222. package/types/main/state/reducers/updateMetaReducer.d.ts +10 -0
  223. package/types/main/state/reducers/updateMetaReducer.d.ts.map +1 -0
  224. package/types/main/state/reducers/userReducer.d.ts.map +1 -1
  225. package/types/main/state/useStallionEvents.d.ts +12 -0
  226. package/types/main/state/useStallionEvents.d.ts.map +1 -0
  227. package/types/main/utils/ErrorBoundary.d.ts +1 -1
  228. package/types/main/utils/ErrorBoundary.d.ts.map +1 -1
  229. package/types/main/utils/StallionEventEmitter.d.ts +11 -0
  230. package/types/main/utils/StallionEventEmitter.d.ts.map +1 -0
  231. package/types/main/utils/StallionNativeUtils.d.ts +11 -0
  232. package/types/main/utils/StallionNativeUtils.d.ts.map +1 -0
  233. package/types/main/utils/debounce.d.ts +3 -0
  234. package/types/main/utils/debounce.d.ts.map +1 -0
  235. package/types/main/utils/useApiClient.d.ts +8 -0
  236. package/types/main/utils/useApiClient.d.ts.map +1 -0
  237. package/types/main/utils/useStallionUpdate.d.ts +3 -0
  238. package/types/main/utils/useStallionUpdate.d.ts.map +1 -0
  239. package/types/main/utils/withStallion.d.ts +1 -2
  240. package/types/main/utils/withStallion.d.ts.map +1 -1
  241. package/types/types/config.types.d.ts +16 -0
  242. package/types/types/config.types.d.ts.map +1 -0
  243. package/types/types/globalProvider.types.d.ts +10 -10
  244. package/types/types/globalProvider.types.d.ts.map +1 -1
  245. package/types/types/meta.types.d.ts +18 -3
  246. package/types/types/meta.types.d.ts.map +1 -1
  247. package/types/types/updateMeta.types.d.ts +37 -0
  248. package/types/types/updateMeta.types.d.ts.map +1 -0
  249. package/types/types/user.types.d.ts +5 -20
  250. package/types/types/user.types.d.ts.map +1 -1
  251. package/types/types/utils.types.d.ts +15 -11
  252. package/types/types/utils.types.d.ts.map +1 -1
  253. package/android/src/main/java/com/stallion/StallionConstants.java +0 -37
  254. package/android/src/main/java/com/stallion/StallionErrorBoundary.java +0 -49
  255. package/android/src/main/java/com/stallion/StallionStorage.java +0 -54
  256. package/android/src/main/java/com/stallion/StallionZip.java +0 -127
  257. package/ios/main/StallionDownloader.swift +0 -124
  258. package/ios/main/StallionErrorBoundary.h +0 -17
  259. package/ios/main/StallionErrorBoundary.m +0 -62
  260. package/ios/main/StallionUtil.swift +0 -29
  261. package/src/main/components/common/ProfileOverlay/index.js +0 -39
  262. package/src/main/components/common/ProfileOverlay/index.js.map +0 -1
  263. package/src/main/components/common/ProfileOverlay/styles.js +0 -39
  264. package/src/main/components/common/ProfileOverlay/styles.js.map +0 -1
  265. package/src/main/components/modules/login/components/Email.js +0 -41
  266. package/src/main/components/modules/login/components/Email.js.map +0 -1
  267. package/src/main/components/modules/login/components/Otp.js +0 -45
  268. package/src/main/components/modules/login/components/Otp.js.map +0 -1
  269. package/src/main/components/modules/login/components/styles/index.js +0 -28
  270. package/src/main/components/modules/login/components/styles/index.js.map +0 -1
  271. package/src/main/components/modules/login/hooks/useLoginFlow.js +0 -60
  272. package/src/main/components/modules/login/hooks/useLoginFlow.js.map +0 -1
  273. package/src/main/utils/SharedDataManager.js +0 -34
  274. package/src/main/utils/SharedDataManager.js.map +0 -1
  275. package/src/main/utils/StallionNaitveUtils.js +0 -7
  276. package/src/main/utils/StallionNaitveUtils.js.map +0 -1
  277. package/src/main/utils/apiUtils.js +0 -16
  278. package/src/main/utils/apiUtils.js.map +0 -1
  279. package/types/main/components/common/ProfileOverlay/index.d.ts +0 -10
  280. package/types/main/components/common/ProfileOverlay/index.d.ts.map +0 -1
  281. package/types/main/components/common/ProfileOverlay/styles.d.ts +0 -36
  282. package/types/main/components/common/ProfileOverlay/styles.d.ts.map +0 -1
  283. package/types/main/components/modules/login/components/Email.d.ts +0 -13
  284. package/types/main/components/modules/login/components/Email.d.ts.map +0 -1
  285. package/types/main/components/modules/login/components/Otp.d.ts +0 -12
  286. package/types/main/components/modules/login/components/Otp.d.ts.map +0 -1
  287. package/types/main/components/modules/login/components/styles/index.d.ts +0 -25
  288. package/types/main/components/modules/login/components/styles/index.d.ts.map +0 -1
  289. package/types/main/components/modules/login/hooks/useLoginFlow.d.ts +0 -18
  290. package/types/main/components/modules/login/hooks/useLoginFlow.d.ts.map +0 -1
  291. package/types/main/utils/SharedDataManager.d.ts +0 -18
  292. package/types/main/utils/SharedDataManager.d.ts.map +0 -1
  293. package/types/main/utils/StallionNaitveUtils.d.ts +0 -7
  294. package/types/main/utils/StallionNaitveUtils.d.ts.map +0 -1
  295. package/types/main/utils/apiUtils.d.ts +0 -7
  296. package/types/main/utils/apiUtils.d.ts.map +0 -1
@@ -0,0 +1,94 @@
1
+ //
2
+ // StallionExceptionHandler.m
3
+ // react-native-stallion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 29/01/25.
6
+ //
7
+
8
+ #import "StallionExceptionHandler.h"
9
+ #import "StallionStateManager.h"
10
+ #import "StallionEventHandler.h"
11
+ #import "StallionSlotManager.h"
12
+ #import "StallionMeta.h"
13
+ #import "StallionMetaConstants.h"
14
+ #import "StallionObjConstants.h"
15
+
16
+ @implementation StallionExceptionHandler
17
+
18
+ NSUncaughtExceptionHandler *_defaultExceptionHandler;
19
+
20
+ + (void)initExceptionHandler {
21
+ if (!_defaultExceptionHandler) {
22
+ _defaultExceptionHandler = NSGetUncaughtExceptionHandler();
23
+ }
24
+ NSSetUncaughtExceptionHandler(&handleException);
25
+ }
26
+
27
+ BOOL exceptionAlertDismissed = FALSE;
28
+
29
+ void handleException(NSException *exception) {
30
+ StallionStateManager *stateManager = [StallionStateManager sharedInstance];
31
+ StallionMeta *meta = stateManager.stallionMeta;
32
+ BOOL isAutoRollback = !stateManager.isMounted;
33
+
34
+ NSString *readableError = [exception reason];
35
+
36
+ if (readableError.length > 900) {
37
+ readableError = [readableError substringToIndex:900];
38
+ }
39
+
40
+ if (meta.switchState == SwitchStateProd) {
41
+ NSString *currentHash = [meta getActiveReleaseHash] ?: @"";
42
+
43
+ [[StallionEventHandler sharedInstance] cacheEvent:StallionObjConstants.exception_prod_event
44
+ eventPayload:@{
45
+ @"meta": readableError,
46
+ StallionObjConstants.release_hash_key: currentHash,
47
+ StallionObjConstants.is_auto_rollback_key: isAutoRollback ? @"true" : @"false"
48
+ }];
49
+ if (isAutoRollback) {
50
+ [StallionSlotManager rollbackProdWithAutoRollback:YES errorString:readableError];
51
+ }
52
+
53
+ } else if (meta.switchState == SwitchStateStage) {
54
+ [StallionSlotManager rollbackStage];
55
+
56
+ [[StallionEventHandler sharedInstance] cacheEvent:StallionObjConstants.exception_stage_event
57
+ eventPayload:@{
58
+ @"meta": readableError,
59
+ StallionObjConstants.release_hash_key: meta.stageNewHash,
60
+ StallionObjConstants.is_auto_rollback_key: isAutoRollback ? @"true" : @"false"
61
+ }];
62
+
63
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Stallion Exception Handler"
64
+ message:[NSString stringWithFormat:@"%@\n%@",
65
+ @"A crash occurred in the app. Build was rolled back. Check crash report below. Continue crash to invoke other exception handlers. \n \n",
66
+ readableError]
67
+ preferredStyle:UIAlertControllerStyleAlert];
68
+
69
+ [alert addAction:[UIAlertAction actionWithTitle:@"Continue Crash"
70
+ style:UIAlertActionStyleDefault
71
+ handler:^(UIAlertAction *action) {
72
+ exceptionAlertDismissed = TRUE;
73
+ }]];
74
+
75
+ UIApplication *app = [UIApplication sharedApplication];
76
+ UIViewController *rootViewController = app.delegate.window.rootViewController;
77
+
78
+ dispatch_async(dispatch_get_main_queue(), ^{
79
+ [rootViewController presentViewController:alert animated:YES completion:nil];
80
+ });
81
+
82
+ while (exceptionAlertDismissed == FALSE) {
83
+ [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
84
+ }
85
+ }
86
+
87
+ // Call default exception handler if available
88
+ if (_defaultExceptionHandler) {
89
+ _defaultExceptionHandler(exception);
90
+ }
91
+ }
92
+
93
+ @end
94
+
@@ -0,0 +1,147 @@
1
+ //
2
+ // StallionFileDownloader.swift
3
+ // react-native-stallion
4
+ //
5
+ // Updated by Thor963 on 17/05/23.
6
+ //
7
+
8
+ import Foundation
9
+ import ZIPFoundation
10
+
11
+ class StallionFileDownloader: NSObject {
12
+ private lazy var urlSession = URLSession(configuration: .default,
13
+ delegate: self,
14
+ delegateQueue: nil)
15
+ private var downloadTask: URLSessionDownloadTask?
16
+ private var _resolve: RCTPromiseResolveBlock?
17
+ private var _reject: RCTPromiseRejectBlock?
18
+ private var _onProgress: ((Float) -> Void)?
19
+ private var lastSentProgress: Float = 0
20
+ private var _downloadDirectory: String?
21
+
22
+ private let queue = DispatchQueue(label: "com.stallion.networkmanager", qos: .background)
23
+
24
+ override init() {
25
+ super.init()
26
+ }
27
+
28
+ func downloadBundle(url: URL, downloadDirectory: String, onProgress: @escaping ((Float) -> Void), resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
29
+ queue.async {
30
+ do {
31
+ self._resolve = resolve
32
+ self._reject = reject
33
+ self._onProgress = onProgress
34
+ self._downloadDirectory = downloadDirectory
35
+
36
+ // Prepare for download
37
+ let downloadedZip = try self.prepareForDownload(downloadDirectory: downloadDirectory)
38
+
39
+ // Create request
40
+ var request = URLRequest(url: url)
41
+ request.httpMethod = "GET"
42
+
43
+ let appToken = StallionStateManager.sharedInstance().stallionConfig.appToken ?? ""
44
+ let sdkToken = StallionStateManager.sharedInstance().stallionConfig.sdkToken ?? ""
45
+
46
+ if !appToken.isEmpty {
47
+ request.setValue(appToken, forHTTPHeaderField: StallionConstants.STALLION_APP_TOKEN_KEY)
48
+ }
49
+ if !sdkToken.isEmpty {
50
+ request.setValue(sdkToken, forHTTPHeaderField: StallionConstants.STALLION_SDK_TOKEN_KEY)
51
+ }
52
+
53
+ // Initiate download
54
+ self.downloadTask = self.urlSession.downloadTask(with: request)
55
+ self.downloadTask?.resume()
56
+
57
+ } catch {
58
+ reject("500", "Error preparing for download: \(error.localizedDescription)", error as NSError)
59
+ }
60
+ }
61
+ }
62
+
63
+ private func prepareForDownload(downloadDirectory: String) throws -> URL {
64
+ let downloadFolder = URL(fileURLWithPath: downloadDirectory, isDirectory: true)
65
+ let fileManager = FileManager.default
66
+
67
+ // Delete existing folder if it exists
68
+ if fileManager.fileExists(atPath: downloadFolder.path) {
69
+ try fileManager.removeItem(at: downloadFolder)
70
+ }
71
+
72
+ // Create new download folder
73
+ try fileManager.createDirectory(at: downloadFolder, withIntermediateDirectories: true, attributes: nil)
74
+
75
+ // Return path to zip file
76
+ return downloadFolder.appendingPathComponent(StallionConstants.FilePaths.ZipFolderName).appendingPathExtension(StallionConstants.FilePaths.ZipExtension)
77
+ }
78
+
79
+ private func validateAndUnzip(downloadedZip: URL, destDirectory: String) throws {
80
+ let fileManager = FileManager.default
81
+ let destFolder = URL(fileURLWithPath: destDirectory, isDirectory: true)
82
+ let otaBundle = destFolder.appendingPathComponent(StallionConstants.FilePaths.ZipFolderName).appendingPathComponent(StallionConstants.FilePaths.JSFileName)
83
+
84
+ // Validate the ZIP file
85
+ guard try isValidZip(downloadedZip: downloadedZip) else {
86
+ throw NSError(domain: "Invalid ZIP file", code: 500)
87
+ }
88
+
89
+ // Unzip the file
90
+ try fileManager.unzipItem(at: downloadedZip, to: destFolder)
91
+
92
+ // Verify that the extracted bundle exists
93
+ guard fileManager.fileExists(atPath: otaBundle.path) else {
94
+ throw NSError(domain: "Corrupted file error", code: 500)
95
+ }
96
+
97
+ // Clean up the ZIP file
98
+ try fileManager.removeItem(at: downloadedZip)
99
+
100
+ self._resolve?(StallionConstants.DownloadPromiseResponses.Success)
101
+ }
102
+
103
+ private func isValidZip(downloadedZip: URL) throws -> Bool {
104
+ let headerSize = 4
105
+
106
+ guard let inputStream = InputStream(url: downloadedZip) else {
107
+ throw NSError(domain: "Cannot open ZIP file", code: 500)
108
+ }
109
+
110
+ inputStream.open()
111
+ defer { inputStream.close() }
112
+
113
+ var header = [UInt8](repeating: 0, count: headerSize)
114
+ let bytesRead = inputStream.read(&header, maxLength: headerSize)
115
+
116
+ guard bytesRead == headerSize else { return false }
117
+ return header == [0x50, 0x4B, 0x03, 0x04] // PKZIP magic number
118
+ }
119
+ }
120
+
121
+ extension StallionFileDownloader: URLSessionDownloadDelegate {
122
+ func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
123
+ let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
124
+ if progress - self.lastSentProgress > StallionConstants.PROGRESS_EVENT_THRESHOLD {
125
+ self.lastSentProgress = progress
126
+ self._onProgress?(progress)
127
+ }
128
+ }
129
+
130
+ func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
131
+ do {
132
+ if let downloadDirectory = self._downloadDirectory {
133
+ try self.validateAndUnzip(downloadedZip: location, destDirectory: downloadDirectory)
134
+ } else {
135
+ throw NSError(domain: "Destination folder not found while unzipping", code: 500)
136
+ }
137
+ } catch {
138
+ self._reject?("500", "File validation/unzipping failed: \(error.localizedDescription)", error as NSError)
139
+ }
140
+ }
141
+
142
+ func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
143
+ if let error = error {
144
+ self._reject?("500", "Network error: \(error.localizedDescription)", error as NSError)
145
+ }
146
+ }
147
+ }
@@ -0,0 +1,20 @@
1
+ //
2
+ // StallionFileManager.h
3
+ // react-native-stallion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 29/01/25.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ NS_ASSUME_NONNULL_BEGIN
11
+
12
+ @interface StallionFileManager : NSObject
13
+
14
+ + (void)deleteFileOrFolderSilently:(NSString *)filePath;
15
+ + (void)moveFileFrom:(NSString *)fromPath to:(NSString *)toPath;
16
+ + (void)copyFileOrDirectoryFrom:(NSString *)sourcePath to:(NSString *)destinationPath;
17
+
18
+ @end
19
+
20
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,126 @@
1
+ //
2
+ // StallionFileManager.m
3
+ // react-native-stallion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 29/01/25.
6
+ //
7
+ #import "StallionFileManager.h"
8
+
9
+ @implementation StallionFileManager
10
+
11
+ + (void)deleteFileOrFolderSilently:(NSString *)filePath {
12
+ NSFileManager *fileManager = [NSFileManager defaultManager];
13
+ NSError *error = nil;
14
+ BOOL isDirectory = NO;
15
+
16
+ if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
17
+ if (isDirectory) {
18
+ NSArray *contents = [fileManager contentsOfDirectoryAtPath:filePath error:&error];
19
+ if (error) {
20
+ NSLog(@"Failed to list contents of directory: %@", error.localizedDescription);
21
+ return;
22
+ }
23
+ for (NSString *content in contents) {
24
+ NSString *fullPath = [filePath stringByAppendingPathComponent:content];
25
+ [self deleteFileOrFolderSilently:fullPath];
26
+ }
27
+ }
28
+ if (![fileManager removeItemAtPath:filePath error:&error]) {
29
+ NSLog(@"Failed to delete file or folder: %@", error.localizedDescription);
30
+ }
31
+ }
32
+ }
33
+
34
+ + (void)moveFileFrom:(NSString *)fromPath to:(NSString *)toPath {
35
+ NSFileManager *fileManager = [NSFileManager defaultManager];
36
+ NSError *error = nil;
37
+
38
+ // Ensure destination directory exists
39
+ NSString *destinationDirectory = [toPath stringByDeletingLastPathComponent];
40
+ if (![fileManager fileExistsAtPath:destinationDirectory]) {
41
+ if (![fileManager createDirectoryAtPath:destinationDirectory
42
+ withIntermediateDirectories:YES
43
+ attributes:nil
44
+ error:&error]) {
45
+ NSLog(@"Failed to create destination directory: %@", error.localizedDescription);
46
+ return;
47
+ }
48
+ }
49
+
50
+ // Attempt to move the file
51
+ if ([fileManager fileExistsAtPath:toPath]) {
52
+ [self deleteFileOrFolderSilently:toPath];
53
+ }
54
+
55
+ if (![fileManager moveItemAtPath:fromPath toPath:toPath error:&error]) {
56
+ NSLog(@"Failed to move file: %@", error.localizedDescription);
57
+ // Fallback: Copy the file and delete the original
58
+ [self copyFileOrDirectoryFrom:fromPath to:toPath];
59
+ [self deleteFileOrFolderSilently:fromPath];
60
+ }
61
+ }
62
+
63
+ + (void)copyFileOrDirectoryFrom:(NSString *)sourcePath to:(NSString *)destinationPath {
64
+ NSFileManager *fileManager = [NSFileManager defaultManager];
65
+ NSError *error = nil;
66
+
67
+ BOOL isDirectory = NO;
68
+ if (![fileManager fileExistsAtPath:sourcePath isDirectory:&isDirectory]) {
69
+ NSLog(@"Source does not exist: %@", sourcePath);
70
+ return;
71
+ }
72
+
73
+ if (isDirectory) {
74
+ // Copy directory recursively
75
+ [self copyDirectoryFrom:sourcePath to:destinationPath];
76
+ } else {
77
+ // Copy individual file
78
+ if (![fileManager copyItemAtPath:sourcePath toPath:destinationPath error:&error]) {
79
+ NSLog(@"Failed to copy file: %@", error.localizedDescription);
80
+ }
81
+ }
82
+ }
83
+
84
+ #pragma mark - Private Helper Methods
85
+
86
+ + (void)copyDirectoryFrom:(NSString *)sourceDirectory to:(NSString *)destinationDirectory {
87
+ NSFileManager *fileManager = [NSFileManager defaultManager];
88
+ NSError *error = nil;
89
+
90
+ // Ensure destination directory exists
91
+ if (![fileManager fileExistsAtPath:destinationDirectory]) {
92
+ if (![fileManager createDirectoryAtPath:destinationDirectory
93
+ withIntermediateDirectories:YES
94
+ attributes:nil
95
+ error:&error]) {
96
+ NSLog(@"Failed to create destination directory: %@", error.localizedDescription);
97
+ return;
98
+ }
99
+ }
100
+
101
+ NSArray *contents = [fileManager contentsOfDirectoryAtPath:sourceDirectory error:&error];
102
+ if (error) {
103
+ NSLog(@"Failed to list contents of directory: %@", error.localizedDescription);
104
+ return;
105
+ }
106
+
107
+ for (NSString *content in contents) {
108
+ NSString *sourcePath = [sourceDirectory stringByAppendingPathComponent:content];
109
+ NSString *destinationPath = [destinationDirectory stringByAppendingPathComponent:content];
110
+ BOOL isDirectory = NO;
111
+
112
+ if ([fileManager fileExistsAtPath:sourcePath isDirectory:&isDirectory]) {
113
+ if (isDirectory) {
114
+ // Recursively copy subdirectories
115
+ [self copyDirectoryFrom:sourcePath to:destinationPath];
116
+ } else {
117
+ // Copy individual file
118
+ if (![fileManager copyItemAtPath:sourcePath toPath:destinationPath error:&error]) {
119
+ NSLog(@"Failed to copy file: %@", error.localizedDescription);
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ @end
@@ -0,0 +1,29 @@
1
+ //
2
+ // StallionMeta.h
3
+ // DoubleConversion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 28/01/25.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "StallionMetaConstants.h"
10
+
11
+ @interface StallionMeta : NSObject
12
+
13
+ @property (nonatomic, assign) SwitchState switchState;
14
+ @property (nonatomic, assign) SlotStates currentProdSlot;
15
+ @property (nonatomic, assign) SlotStates currentStageSlot;
16
+
17
+ @property (nonatomic, copy) NSString *stageTempHash;
18
+ @property (nonatomic, copy) NSString *stageNewHash;
19
+ @property (nonatomic, copy) NSString *prodTempHash;
20
+ @property (nonatomic, copy) NSString *prodNewHash;
21
+ @property (nonatomic, copy) NSString *prodStableHash;
22
+ @property (nonatomic, copy) NSString *lastRolledBackHash;
23
+
24
+ - (void)reset;
25
+ - (NSDictionary *)toDictionary;
26
+ - (NSString *)getActiveReleaseHash;
27
+ + (instancetype)fromDictionary:(NSDictionary *)dict;
28
+
29
+ @end
@@ -0,0 +1,98 @@
1
+ //
2
+ // StallionMeta.m
3
+ // DoubleConversion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 28/01/25.
6
+ //
7
+
8
+ #import "StallionMeta.h"
9
+
10
+ @implementation StallionMeta
11
+
12
+ - (instancetype)init {
13
+ self = [super init];
14
+ if (self) [self reset];
15
+ return self;
16
+ }
17
+
18
+ - (void)reset {
19
+ self.switchState = SwitchStateProd;
20
+ self.currentProdSlot = SlotStateDefaultSlot;
21
+ self.currentStageSlot = SlotStateDefaultSlot;
22
+
23
+ self.stageTempHash = @"";
24
+ self.stageNewHash = @"";
25
+ self.prodTempHash = @"";
26
+ self.prodNewHash = @"";
27
+ self.prodStableHash = @"";
28
+ self.lastRolledBackHash = @"";
29
+ }
30
+
31
+ - (NSDictionary *)toDictionary {
32
+ @try {
33
+ return @{
34
+ @"switchState": [StallionMetaConstants stringFromSwitchState:self.switchState] ?: @"",
35
+ @"stageSlot": @{
36
+ @"tempHash": self.stageTempHash ?: @"",
37
+ @"newHash": self.stageNewHash ?: @"",
38
+ @"currentSlot": [StallionMetaConstants stringFromSlotState:self.currentStageSlot] ?: @""
39
+ },
40
+ @"prodSlot": @{
41
+ @"tempHash": self.prodTempHash ?: @"",
42
+ @"newHash": self.prodNewHash ?: @"",
43
+ @"stableHash": self.prodStableHash ?: @"",
44
+ @"currentSlot": [StallionMetaConstants stringFromSlotState:self.currentProdSlot] ?: @""
45
+ },
46
+ @"lastRolledBackHash": self.lastRolledBackHash ?: @""
47
+ };
48
+ } @catch (NSException *exception) {
49
+ NSLog(@"Error in toDictionary: %@", exception.reason);
50
+ return @{};
51
+ }
52
+ }
53
+
54
+ - (NSString *)getActiveReleaseHash {
55
+ if (![self.prodTempHash isEqual:@""]) {
56
+ return self.prodTempHash;
57
+ }
58
+ switch (self.currentProdSlot) {
59
+ case SlotStateNewSlot:
60
+ return self.prodNewHash;
61
+ case SlotStateStableSlot:
62
+ return self.prodStableHash;
63
+ default:
64
+ return @"";
65
+ }
66
+ }
67
+
68
+ + (instancetype)fromDictionary:(NSDictionary *)dict {
69
+ @try {
70
+ if (!dict || ![dict isKindOfClass:[NSDictionary class]]) {
71
+ return [[StallionMeta alloc] init];
72
+ }
73
+
74
+ StallionMeta *meta = [[StallionMeta alloc] init];
75
+
76
+ meta.switchState = [StallionMetaConstants switchStateFromString:dict[@"switchState"] ?: @"prod"];
77
+ NSDictionary *stageSlot = dict[@"stageSlot"];
78
+ NSDictionary *prodSlot = dict[@"prodSlot"];
79
+
80
+ meta.stageTempHash = stageSlot[@"tempHash"] ?: @"";
81
+ meta.stageNewHash = stageSlot[@"newHash"] ?: @"";
82
+ meta.currentStageSlot = [StallionMetaConstants slotStateFromString:stageSlot[@"currentSlot"] ?: @"default_slot"];
83
+
84
+ meta.prodTempHash = prodSlot[@"tempHash"] ?: @"";
85
+ meta.prodNewHash = prodSlot[@"newHash"] ?: @"";
86
+ meta.prodStableHash = prodSlot[@"stableHash"] ?: @"";
87
+ meta.currentProdSlot = [StallionMetaConstants slotStateFromString:prodSlot[@"currentSlot"] ?: @"default_slot"];
88
+
89
+ meta.lastRolledBackHash = dict[@"lastRolledBackHash"] ?: @"";
90
+
91
+ return meta;
92
+ } @catch (NSException *exception) {
93
+ NSLog(@"Error in fromDictionary: %@", exception.reason);
94
+ return [[StallionMeta alloc] init];
95
+ }
96
+ }
97
+
98
+ @end
@@ -0,0 +1,28 @@
1
+ //
2
+ // StallionMetaConstants.h
3
+ // DoubleConversion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 28/01/25.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ typedef NS_ENUM(NSInteger, SwitchState) {
11
+ SwitchStateProd,
12
+ SwitchStateStage
13
+ };
14
+
15
+ typedef NS_ENUM(NSInteger, SlotStates) {
16
+ SlotStateNewSlot,
17
+ SlotStateStableSlot,
18
+ SlotStateDefaultSlot
19
+ };
20
+
21
+ @interface StallionMetaConstants : NSObject
22
+
23
+ + (SwitchState)switchStateFromString:(NSString *)value;
24
+ + (SlotStates)slotStateFromString:(NSString *)value;
25
+ + (NSString *)stringFromSwitchState:(SwitchState)state;
26
+ + (NSString *)stringFromSlotState:(SlotStates)state;
27
+
28
+ @end
@@ -0,0 +1,42 @@
1
+ //
2
+ // StallionMetaConstants.m
3
+ // DoubleConversion
4
+ //
5
+ // Created by Jasbir Singh Shergill on 28/01/25.
6
+ //
7
+
8
+ #import "StallionMetaConstants.h"
9
+
10
+ @implementation StallionMetaConstants
11
+
12
+ + (SwitchState)switchStateFromString:(NSString *)value {
13
+ if ([value isEqualToString:@"PROD"]) return SwitchStateProd;
14
+ if ([value isEqualToString:@"STAGE"]) return SwitchStateStage;
15
+ @throw [NSException exceptionWithName:@"InvalidSwitchStateException" reason:@"Invalid SwitchState" userInfo:nil];
16
+ }
17
+
18
+ + (SlotStates)slotStateFromString:(NSString *)value {
19
+ if ([value isEqualToString:@"NEW_SLOT"]) return SlotStateNewSlot;
20
+ if ([value isEqualToString:@"STABLE_SLOT"]) return SlotStateStableSlot;
21
+ if ([value isEqualToString:@"DEFAULT_SLOT"]) return SlotStateDefaultSlot;
22
+ return SlotStateDefaultSlot;
23
+ }
24
+
25
+ + (NSString *)stringFromSwitchState:(SwitchState)state {
26
+ switch (state) {
27
+ case SwitchStateProd: return @"PROD";
28
+ case SwitchStateStage: return @"STAGE";
29
+ default: return @"unknown";
30
+ }
31
+ }
32
+
33
+ + (NSString *)stringFromSlotState:(SlotStates)state {
34
+ switch (state) {
35
+ case SlotStateNewSlot: return @"NEW_SLOT";
36
+ case SlotStateStableSlot: return @"STABLE_SLOT";
37
+ case SlotStateDefaultSlot: return @"DEFAULT_SLOT";
38
+ default: return @"unknown";
39
+ }
40
+ }
41
+
42
+ @end