mobilyflow-react-native-sdk 0.0.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 (46) hide show
  1. package/LICENSE +20 -0
  2. package/MobilyflowReactNativeSdk.podspec +52 -0
  3. package/README.md +33 -0
  4. package/android/build.gradle +114 -0
  5. package/android/generated/java/com/mobilyflowreactnativesdk/NativeMobilyflowReactNativeSdkSpec.java +89 -0
  6. package/android/generated/jni/CMakeLists.txt +36 -0
  7. package/android/generated/jni/RNMobilyflowReactNativeSdkSpec-generated.cpp +104 -0
  8. package/android/generated/jni/RNMobilyflowReactNativeSdkSpec.h +31 -0
  9. package/android/generated/jni/react/renderer/components/RNMobilyflowReactNativeSdkSpec/RNMobilyflowReactNativeSdkSpecJSI-generated.cpp +124 -0
  10. package/android/generated/jni/react/renderer/components/RNMobilyflowReactNativeSdkSpec/RNMobilyflowReactNativeSdkSpecJSI.h +287 -0
  11. package/android/gradle.properties +5 -0
  12. package/android/src/main/AndroidManifest.xml +3 -0
  13. package/android/src/main/AndroidManifestNew.xml +2 -0
  14. package/android/src/main/java/com/mobilyflowreactnativesdk/MobilyflowReactNativeSdkModule.kt +183 -0
  15. package/android/src/main/java/com/mobilyflowreactnativesdk/MobilyflowReactNativeSdkPackage.kt +32 -0
  16. package/android/src/main/java/com/mobilyflowreactnativesdk/ParserUtils.kt +149 -0
  17. package/ios/MobilyflowReactNativeSdk.h +7 -0
  18. package/ios/MobilyflowReactNativeSdk.mm +204 -0
  19. package/ios/Utils/ParserMobilyPurchaseSDKOptions.h +21 -0
  20. package/ios/Utils/ParserMobilyPurchaseSDKOptions.mm +25 -0
  21. package/ios/Utils/Utils.h +18 -0
  22. package/ios/Utils/Utils.m +22 -0
  23. package/ios/generated/RNMobilyflowReactNativeSdkSpec/RNMobilyflowReactNativeSdkSpec-generated.mm +134 -0
  24. package/ios/generated/RNMobilyflowReactNativeSdkSpec/RNMobilyflowReactNativeSdkSpec.h +161 -0
  25. package/ios/generated/RNMobilyflowReactNativeSdkSpecJSI-generated.cpp +124 -0
  26. package/ios/generated/RNMobilyflowReactNativeSdkSpecJSI.h +287 -0
  27. package/package.json +183 -0
  28. package/react-native.config.js +12 -0
  29. package/src/NativeMobilyflowReactNativeSdk.ts +46 -0
  30. package/src/entities/mobily-customer-entitlement.ts +37 -0
  31. package/src/entities/mobily-one-time-product.ts +11 -0
  32. package/src/entities/mobily-product.ts +34 -0
  33. package/src/entities/mobily-subscription-group.ts +20 -0
  34. package/src/entities/mobily-subscription-offer.ts +16 -0
  35. package/src/entities/mobily-subscription-product.ts +14 -0
  36. package/src/enums/mobily-environment.ts +5 -0
  37. package/src/enums/period-unit.ts +5 -0
  38. package/src/enums/platform.ts +4 -0
  39. package/src/enums/product-status.ts +5 -0
  40. package/src/enums/product-type.ts +4 -0
  41. package/src/enums/webhook-status.ts +5 -0
  42. package/src/errors/mobily-error.ts +18 -0
  43. package/src/errors/mobily-purchase-error.ts +30 -0
  44. package/src/errors/mobily-transfer-ownership-error.ts +20 -0
  45. package/src/index.tsx +153 -0
  46. package/src/utils/object-transformer.ts +60 -0
@@ -0,0 +1,287 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GenerateModuleH.js
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include <ReactCommon/TurboModule.h>
13
+ #include <react/bridging/Bridging.h>
14
+
15
+ namespace facebook::react {
16
+
17
+
18
+
19
+ #pragma mark - NativeMobilyflowReactNativeSdkMobilyPurchaseSDKOptions
20
+
21
+ template <typename P0, typename P1, typename P2>
22
+ struct NativeMobilyflowReactNativeSdkMobilyPurchaseSDKOptions {
23
+ P0 languages;
24
+ P1 debug;
25
+ P2 apiURL;
26
+ bool operator==(const NativeMobilyflowReactNativeSdkMobilyPurchaseSDKOptions &other) const {
27
+ return languages == other.languages && debug == other.debug && apiURL == other.apiURL;
28
+ }
29
+ };
30
+
31
+ template <typename T>
32
+ struct NativeMobilyflowReactNativeSdkMobilyPurchaseSDKOptionsBridging {
33
+ static T types;
34
+
35
+ static T fromJs(
36
+ jsi::Runtime &rt,
37
+ const jsi::Object &value,
38
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
39
+ T result{
40
+ bridging::fromJs<decltype(types.languages)>(rt, value.getProperty(rt, "languages"), jsInvoker),
41
+ bridging::fromJs<decltype(types.debug)>(rt, value.getProperty(rt, "debug"), jsInvoker),
42
+ bridging::fromJs<decltype(types.apiURL)>(rt, value.getProperty(rt, "apiURL"), jsInvoker)};
43
+ return result;
44
+ }
45
+
46
+ #ifdef DEBUG
47
+ static jsi::Array languagesToJs(jsi::Runtime &rt, decltype(types.languages) value) {
48
+ return bridging::toJs(rt, value);
49
+ }
50
+
51
+ static bool debugToJs(jsi::Runtime &rt, decltype(types.debug) value) {
52
+ return bridging::toJs(rt, value);
53
+ }
54
+
55
+ static jsi::String apiURLToJs(jsi::Runtime &rt, decltype(types.apiURL) value) {
56
+ return bridging::toJs(rt, value);
57
+ }
58
+ #endif
59
+
60
+ static jsi::Object toJs(
61
+ jsi::Runtime &rt,
62
+ const T &value,
63
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
64
+ auto result = facebook::jsi::Object(rt);
65
+ if (value.languages) {
66
+ result.setProperty(rt, "languages", bridging::toJs(rt, value.languages.value(), jsInvoker));
67
+ }
68
+ if (value.debug) {
69
+ result.setProperty(rt, "debug", bridging::toJs(rt, value.debug.value(), jsInvoker));
70
+ }
71
+ if (value.apiURL) {
72
+ result.setProperty(rt, "apiURL", bridging::toJs(rt, value.apiURL.value(), jsInvoker));
73
+ }
74
+ return result;
75
+ }
76
+ };
77
+
78
+
79
+
80
+ #pragma mark - NativeMobilyflowReactNativeSdkPurchaseOptions
81
+
82
+ template <typename P0, typename P1>
83
+ struct NativeMobilyflowReactNativeSdkPurchaseOptions {
84
+ P0 offerId;
85
+ P1 quantity;
86
+ bool operator==(const NativeMobilyflowReactNativeSdkPurchaseOptions &other) const {
87
+ return offerId == other.offerId && quantity == other.quantity;
88
+ }
89
+ };
90
+
91
+ template <typename T>
92
+ struct NativeMobilyflowReactNativeSdkPurchaseOptionsBridging {
93
+ static T types;
94
+
95
+ static T fromJs(
96
+ jsi::Runtime &rt,
97
+ const jsi::Object &value,
98
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
99
+ T result{
100
+ bridging::fromJs<decltype(types.offerId)>(rt, value.getProperty(rt, "offerId"), jsInvoker),
101
+ bridging::fromJs<decltype(types.quantity)>(rt, value.getProperty(rt, "quantity"), jsInvoker)};
102
+ return result;
103
+ }
104
+
105
+ #ifdef DEBUG
106
+ static jsi::String offerIdToJs(jsi::Runtime &rt, decltype(types.offerId) value) {
107
+ return bridging::toJs(rt, value);
108
+ }
109
+
110
+ static double quantityToJs(jsi::Runtime &rt, decltype(types.quantity) value) {
111
+ return bridging::toJs(rt, value);
112
+ }
113
+ #endif
114
+
115
+ static jsi::Object toJs(
116
+ jsi::Runtime &rt,
117
+ const T &value,
118
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
119
+ auto result = facebook::jsi::Object(rt);
120
+ result.setProperty(rt, "offerId", bridging::toJs(rt, value.offerId, jsInvoker));
121
+ result.setProperty(rt, "quantity", bridging::toJs(rt, value.quantity, jsInvoker));
122
+ return result;
123
+ }
124
+ };
125
+
126
+ class JSI_EXPORT NativeMobilyflowReactNativeSdkCxxSpecJSI : public TurboModule {
127
+ protected:
128
+ NativeMobilyflowReactNativeSdkCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
129
+
130
+ public:
131
+ virtual jsi::String instantiate(jsi::Runtime &rt, jsi::String appId, jsi::String apiKey, double environment, std::optional<jsi::Object> options) = 0;
132
+ virtual void close(jsi::Runtime &rt, jsi::String uuid) = 0;
133
+ virtual jsi::Value login(jsi::Runtime &rt, jsi::String uuid, jsi::String externalId) = 0;
134
+ virtual jsi::Value getProducts(jsi::Runtime &rt, jsi::String uuid, std::optional<jsi::Array> identifiers) = 0;
135
+ virtual jsi::Value getSubscriptionGroups(jsi::Runtime &rt, jsi::String uuid, std::optional<jsi::Array> identifiers) = 0;
136
+ virtual jsi::Value getEntitlementForSubscription(jsi::Runtime &rt, jsi::String uuid, jsi::String subscriptionGroupId) = 0;
137
+ virtual jsi::Value getEntitlement(jsi::Runtime &rt, jsi::String uuid, jsi::String productId) = 0;
138
+ virtual jsi::Value getEntitlements(jsi::Runtime &rt, jsi::String uuid, jsi::Array productIds) = 0;
139
+ virtual jsi::Value requestTransferOwnership(jsi::Runtime &rt, jsi::String uuid) = 0;
140
+ virtual jsi::Value openManageSubscription(jsi::Runtime &rt, jsi::String uuid) = 0;
141
+ virtual jsi::Value purchaseProduct(jsi::Runtime &rt, jsi::String uuid, jsi::String productId, std::optional<jsi::Object> options) = 0;
142
+ virtual void sendDiagnotic(jsi::Runtime &rt, jsi::String uuid) = 0;
143
+ virtual jsi::Value getStoreCountry(jsi::Runtime &rt, jsi::String uuid) = 0;
144
+
145
+ };
146
+
147
+ template <typename T>
148
+ class JSI_EXPORT NativeMobilyflowReactNativeSdkCxxSpec : public TurboModule {
149
+ public:
150
+ jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
151
+ return delegate_.create(rt, propName);
152
+ }
153
+
154
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override {
155
+ return delegate_.getPropertyNames(runtime);
156
+ }
157
+
158
+ static constexpr std::string_view kModuleName = "MobilyflowReactNativeSdk";
159
+
160
+ protected:
161
+ NativeMobilyflowReactNativeSdkCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
162
+ : TurboModule(std::string{NativeMobilyflowReactNativeSdkCxxSpec::kModuleName}, jsInvoker),
163
+ delegate_(reinterpret_cast<T*>(this), jsInvoker) {}
164
+
165
+
166
+ private:
167
+ class Delegate : public NativeMobilyflowReactNativeSdkCxxSpecJSI {
168
+ public:
169
+ Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
170
+ NativeMobilyflowReactNativeSdkCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {
171
+
172
+ }
173
+
174
+ jsi::String instantiate(jsi::Runtime &rt, jsi::String appId, jsi::String apiKey, double environment, std::optional<jsi::Object> options) override {
175
+ static_assert(
176
+ bridging::getParameterCount(&T::instantiate) == 5,
177
+ "Expected instantiate(...) to have 5 parameters");
178
+
179
+ return bridging::callFromJs<jsi::String>(
180
+ rt, &T::instantiate, jsInvoker_, instance_, std::move(appId), std::move(apiKey), std::move(environment), std::move(options));
181
+ }
182
+ void close(jsi::Runtime &rt, jsi::String uuid) override {
183
+ static_assert(
184
+ bridging::getParameterCount(&T::close) == 2,
185
+ "Expected close(...) to have 2 parameters");
186
+
187
+ return bridging::callFromJs<void>(
188
+ rt, &T::close, jsInvoker_, instance_, std::move(uuid));
189
+ }
190
+ jsi::Value login(jsi::Runtime &rt, jsi::String uuid, jsi::String externalId) override {
191
+ static_assert(
192
+ bridging::getParameterCount(&T::login) == 3,
193
+ "Expected login(...) to have 3 parameters");
194
+
195
+ return bridging::callFromJs<jsi::Value>(
196
+ rt, &T::login, jsInvoker_, instance_, std::move(uuid), std::move(externalId));
197
+ }
198
+ jsi::Value getProducts(jsi::Runtime &rt, jsi::String uuid, std::optional<jsi::Array> identifiers) override {
199
+ static_assert(
200
+ bridging::getParameterCount(&T::getProducts) == 3,
201
+ "Expected getProducts(...) to have 3 parameters");
202
+
203
+ return bridging::callFromJs<jsi::Value>(
204
+ rt, &T::getProducts, jsInvoker_, instance_, std::move(uuid), std::move(identifiers));
205
+ }
206
+ jsi::Value getSubscriptionGroups(jsi::Runtime &rt, jsi::String uuid, std::optional<jsi::Array> identifiers) override {
207
+ static_assert(
208
+ bridging::getParameterCount(&T::getSubscriptionGroups) == 3,
209
+ "Expected getSubscriptionGroups(...) to have 3 parameters");
210
+
211
+ return bridging::callFromJs<jsi::Value>(
212
+ rt, &T::getSubscriptionGroups, jsInvoker_, instance_, std::move(uuid), std::move(identifiers));
213
+ }
214
+ jsi::Value getEntitlementForSubscription(jsi::Runtime &rt, jsi::String uuid, jsi::String subscriptionGroupId) override {
215
+ static_assert(
216
+ bridging::getParameterCount(&T::getEntitlementForSubscription) == 3,
217
+ "Expected getEntitlementForSubscription(...) to have 3 parameters");
218
+
219
+ return bridging::callFromJs<jsi::Value>(
220
+ rt, &T::getEntitlementForSubscription, jsInvoker_, instance_, std::move(uuid), std::move(subscriptionGroupId));
221
+ }
222
+ jsi::Value getEntitlement(jsi::Runtime &rt, jsi::String uuid, jsi::String productId) override {
223
+ static_assert(
224
+ bridging::getParameterCount(&T::getEntitlement) == 3,
225
+ "Expected getEntitlement(...) to have 3 parameters");
226
+
227
+ return bridging::callFromJs<jsi::Value>(
228
+ rt, &T::getEntitlement, jsInvoker_, instance_, std::move(uuid), std::move(productId));
229
+ }
230
+ jsi::Value getEntitlements(jsi::Runtime &rt, jsi::String uuid, jsi::Array productIds) override {
231
+ static_assert(
232
+ bridging::getParameterCount(&T::getEntitlements) == 3,
233
+ "Expected getEntitlements(...) to have 3 parameters");
234
+
235
+ return bridging::callFromJs<jsi::Value>(
236
+ rt, &T::getEntitlements, jsInvoker_, instance_, std::move(uuid), std::move(productIds));
237
+ }
238
+ jsi::Value requestTransferOwnership(jsi::Runtime &rt, jsi::String uuid) override {
239
+ static_assert(
240
+ bridging::getParameterCount(&T::requestTransferOwnership) == 2,
241
+ "Expected requestTransferOwnership(...) to have 2 parameters");
242
+
243
+ return bridging::callFromJs<jsi::Value>(
244
+ rt, &T::requestTransferOwnership, jsInvoker_, instance_, std::move(uuid));
245
+ }
246
+ jsi::Value openManageSubscription(jsi::Runtime &rt, jsi::String uuid) override {
247
+ static_assert(
248
+ bridging::getParameterCount(&T::openManageSubscription) == 2,
249
+ "Expected openManageSubscription(...) to have 2 parameters");
250
+
251
+ return bridging::callFromJs<jsi::Value>(
252
+ rt, &T::openManageSubscription, jsInvoker_, instance_, std::move(uuid));
253
+ }
254
+ jsi::Value purchaseProduct(jsi::Runtime &rt, jsi::String uuid, jsi::String productId, std::optional<jsi::Object> options) override {
255
+ static_assert(
256
+ bridging::getParameterCount(&T::purchaseProduct) == 4,
257
+ "Expected purchaseProduct(...) to have 4 parameters");
258
+
259
+ return bridging::callFromJs<jsi::Value>(
260
+ rt, &T::purchaseProduct, jsInvoker_, instance_, std::move(uuid), std::move(productId), std::move(options));
261
+ }
262
+ void sendDiagnotic(jsi::Runtime &rt, jsi::String uuid) override {
263
+ static_assert(
264
+ bridging::getParameterCount(&T::sendDiagnotic) == 2,
265
+ "Expected sendDiagnotic(...) to have 2 parameters");
266
+
267
+ return bridging::callFromJs<void>(
268
+ rt, &T::sendDiagnotic, jsInvoker_, instance_, std::move(uuid));
269
+ }
270
+ jsi::Value getStoreCountry(jsi::Runtime &rt, jsi::String uuid) override {
271
+ static_assert(
272
+ bridging::getParameterCount(&T::getStoreCountry) == 2,
273
+ "Expected getStoreCountry(...) to have 2 parameters");
274
+
275
+ return bridging::callFromJs<jsi::Value>(
276
+ rt, &T::getStoreCountry, jsInvoker_, instance_, std::move(uuid));
277
+ }
278
+
279
+ private:
280
+ friend class NativeMobilyflowReactNativeSdkCxxSpec;
281
+ T *instance_;
282
+ };
283
+
284
+ Delegate delegate_;
285
+ };
286
+
287
+ } // namespace facebook::react
@@ -0,0 +1,5 @@
1
+ MobilyflowReactNativeSdk_kotlinVersion=2.0.21
2
+ MobilyflowReactNativeSdk_minSdkVersion=24
3
+ MobilyflowReactNativeSdk_targetSdkVersion=34
4
+ MobilyflowReactNativeSdk_compileSdkVersion=35
5
+ MobilyflowReactNativeSdk_ndkVersion=27.1.12297006
@@ -0,0 +1,3 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.mobilyflowreactnativesdk">
3
+ </manifest>
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,183 @@
1
+ package com.mobilyflowreactnativesdk
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.Promise
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReadableArray
7
+ import com.facebook.react.bridge.ReadableMap
8
+ import com.facebook.react.module.annotations.ReactModule
9
+ import com.mobilyflow.mobilypurchasesdk.Enums.MobilyEnvironment
10
+ import com.mobilyflow.mobilypurchasesdk.Exceptions.MobilyException
11
+ import com.mobilyflow.mobilypurchasesdk.Exceptions.MobilyPurchaseException
12
+ import com.mobilyflow.mobilypurchasesdk.Exceptions.MobilyTransferOwnershipException
13
+ import com.mobilyflow.mobilypurchasesdk.MobilyPurchaseSDK
14
+ import com.mobilyflow.mobilypurchasesdk.MobilyPurchaseSDKOptions
15
+ import com.mobilyflow.mobilypurchasesdk.Models.PurchaseOptions
16
+ import java.util.UUID
17
+
18
+ @ReactModule(name = MobilyflowReactNativeSdkModule.NAME)
19
+ class MobilyflowReactNativeSdkModule(reactContext: ReactApplicationContext) : NativeMobilyflowReactNativeSdkSpec(reactContext) {
20
+ private val _sdkInstances = mutableMapOf<String, MobilyPurchaseSDK>()
21
+
22
+ private fun throwError(error: Exception, promise: Promise) {
23
+ when (error) {
24
+ is MobilyException -> promise.reject(error.type.ordinal.toString(), error.message, error)
25
+ is MobilyPurchaseException -> promise.reject(error.type.ordinal.toString(), error.message, error)
26
+ is MobilyTransferOwnershipException -> promise.reject(error.type.ordinal.toString(), error.message, error)
27
+ else -> promise.reject("-1", error.message, error)
28
+ }
29
+ }
30
+
31
+ override fun getName(): String {
32
+ return NAME
33
+ }
34
+
35
+ override fun instantiate(appId: String, apiKey: String, environment: Double, options: ReadableMap?): String {
36
+ val uuid = UUID.randomUUID().toString()
37
+
38
+ var realOptions: MobilyPurchaseSDKOptions? = null
39
+ if (options != null) {
40
+ realOptions = MobilyPurchaseSDKOptions(
41
+ options.getArray("languages").toStringArray(),
42
+ options.optBoolean("debug"),
43
+ options.getString("apiURL")
44
+ )
45
+ }
46
+
47
+ val realEnvironment = MobilyEnvironment.entries.find { x -> x.value == environment.toInt() }
48
+ val sdk = MobilyPurchaseSDK(reactApplicationContext, appId, apiKey, realEnvironment!!, realOptions)
49
+ _sdkInstances[uuid] = sdk
50
+
51
+ return uuid
52
+ }
53
+
54
+ override fun close(uuid: String) {
55
+ _sdkInstances[uuid]!!.close()
56
+ }
57
+
58
+ override fun login(uuid: String, externalId: String, promise: Promise) {
59
+ try {
60
+ _sdkInstances[uuid]!!.login(externalId)
61
+ promise.resolve(1)
62
+ } catch (error: Exception) {
63
+ throwError(error, promise)
64
+ }
65
+ }
66
+
67
+ override fun getProducts(uuid: String, identifiers: ReadableArray?, promise: Promise) {
68
+ try {
69
+ val products = _sdkInstances[uuid]!!.getProducts(identifiers.toStringArray(), false)
70
+ promise.resolve(products.toReadableArray())
71
+ } catch (error: Exception) {
72
+ throwError(error, promise)
73
+ }
74
+ }
75
+
76
+ override fun getSubscriptionGroups(uuid: String, identifiers: ReadableArray?, promise: Promise) {
77
+ try {
78
+ val groups = _sdkInstances[uuid]!!.getSubscriptionGroups(identifiers.toStringArray(), false)
79
+ promise.resolve(groups.toReadableArray())
80
+ } catch (error: Exception) {
81
+ throwError(error, promise)
82
+ }
83
+ }
84
+
85
+ override fun getEntitlementForSubscription(uuid: String, subscriptionGroupId: String, promise: Promise) {
86
+ try {
87
+ val entitlement = _sdkInstances[uuid]!!.getEntitlementForSubscription(subscriptionGroupId)
88
+ promise.resolve(entitlement.toReadableMap())
89
+ } catch (error: Exception) {
90
+ throwError(error, promise)
91
+ }
92
+ }
93
+
94
+ override fun getEntitlement(uuid: String, productId: String, promise: Promise) {
95
+ try {
96
+ val entitlement = _sdkInstances[uuid]!!.getEntitlement(productId)
97
+ promise.resolve(entitlement.toReadableMap())
98
+ } catch (error: Exception) {
99
+ throwError(error, promise)
100
+ }
101
+ }
102
+
103
+ override fun getEntitlements(uuid: String, productIds: ReadableArray, promise: Promise) {
104
+ try {
105
+ val entitlements = _sdkInstances[uuid]!!.getEntitlements(productIds.toStringArray()!!)
106
+ promise.resolve(entitlements.toReadableArray())
107
+ } catch (error: Exception) {
108
+ throwError(error, promise)
109
+ }
110
+ }
111
+
112
+ override fun requestTransferOwnership(uuid: String, promise: Promise) {
113
+ try {
114
+ val status = _sdkInstances[uuid]!!.requestTransferOwnership()
115
+ promise.resolve(status.value)
116
+ } catch (error: Exception) {
117
+ throwError(error, promise)
118
+ }
119
+ }
120
+
121
+ override fun openManageSubscription(uuid: String, promise: Promise) {
122
+ try {
123
+ _sdkInstances[uuid]!!.openManageSubscription()
124
+ promise.resolve(0)
125
+ } catch (error: Exception) {
126
+ throwError(error, promise)
127
+ }
128
+ }
129
+
130
+ override fun purchaseProduct(uuid: String, productId: String, options: ReadableMap?, promise: Promise) {
131
+ try {
132
+ if (reactApplicationContext.currentActivity == null) {
133
+ throw MobilyException(MobilyException.Type.UNKNOWN_ERROR)
134
+ }
135
+
136
+ val sdk = _sdkInstances[uuid]!!
137
+
138
+ val purchaseOptions = PurchaseOptions()
139
+ val offerId = options?.getString("offerId")
140
+
141
+ val product = sdk.getProducts(null, false).find { x -> x.id == productId }
142
+ if (product == null) {
143
+ throw MobilyPurchaseException(MobilyPurchaseException.Type.PRODUCT_UNAVAILABLE)
144
+ }
145
+
146
+ if (offerId != null) {
147
+ if (product.subscriptionProduct!!.baseOffer.id == offerId) {
148
+ purchaseOptions.setOffer(product.subscriptionProduct!!.baseOffer)
149
+ } else if (product.subscriptionProduct!!.freeTrial?.id == offerId) {
150
+ purchaseOptions.setOffer(product.subscriptionProduct!!.freeTrial)
151
+ } else {
152
+ val offer = product.subscriptionProduct!!.promotionalOffers.find { x -> x.id == offerId }
153
+ if (offer != null) {
154
+ purchaseOptions.setOffer(offer)
155
+ }
156
+ }
157
+ }
158
+
159
+ sdk.purchaseProduct(reactApplicationContext.currentActivity!!, product, purchaseOptions)
160
+ } catch (error: Exception) {
161
+ throwError(error, promise)
162
+ }
163
+ }
164
+
165
+ override fun sendDiagnotic(uuid: String) {
166
+ _sdkInstances[uuid]!!.sendDiagnostic()
167
+ }
168
+
169
+ override fun getStoreCountry(uuid: String, promise: Promise) {
170
+ /*try {
171
+ val status = _sdkInstances[uuid]!!.getS()
172
+ promise.resolve(status.value)
173
+ } catch (error: Exception) {
174
+ throwError(error, promise)
175
+ }*/
176
+ // TODO
177
+ return promise.resolve("FRA")
178
+ }
179
+
180
+ companion object {
181
+ const val NAME = "MobilyflowReactNativeSdk"
182
+ }
183
+ }
@@ -0,0 +1,32 @@
1
+ package com.mobilyflowreactnativesdk
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+
9
+ class MobilyflowReactNativeSdkPackage : BaseReactPackage() {
10
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
11
+ return if (name == MobilyflowReactNativeSdkModule.NAME) {
12
+ MobilyflowReactNativeSdkModule(reactContext)
13
+ } else {
14
+ null
15
+ }
16
+ }
17
+
18
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
19
+ return ReactModuleInfoProvider {
20
+ val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
21
+ moduleInfos[MobilyflowReactNativeSdkModule.NAME] = ReactModuleInfo(
22
+ MobilyflowReactNativeSdkModule.NAME,
23
+ MobilyflowReactNativeSdkModule.NAME,
24
+ false, // canOverrideExistingModule
25
+ false, // needsEagerInit
26
+ false, // isCxxModule
27
+ true // isTurboModule
28
+ )
29
+ moduleInfos
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,149 @@
1
+ package com.mobilyflowreactnativesdk
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.ReadableArray
5
+ import com.facebook.react.bridge.ReadableMap
6
+ import com.facebook.react.bridge.WritableArray
7
+ import com.facebook.react.bridge.WritableMap
8
+ import kotlinx.datetime.LocalDateTime
9
+ import kotlinx.datetime.format
10
+ import org.json.JSONArray
11
+ import org.json.JSONObject
12
+ import kotlin.reflect.full.isSubclassOf
13
+ import kotlin.reflect.full.memberProperties
14
+
15
+ /**
16
+ * Take a value and return String, Int, Double, Boolean, ReadableArray or ReadableMap
17
+ */
18
+ private fun getJsonRawValue(value: Any?): Any? {
19
+ when (value) {
20
+ null -> return null
21
+ is String -> return value
22
+ is Int -> return value
23
+ is Double -> return value
24
+ is Boolean -> return value
25
+ is ReadableArray -> return value
26
+ is ReadableMap -> return value
27
+ is LocalDateTime -> return value.format(LocalDateTime.Formats.ISO) + 'Z'
28
+ is Map<*, *> -> return value.toReadableMap()
29
+ is JSONObject -> return value.toReadableMap()
30
+ is Collection<*> -> return value.toReadableArray()
31
+ is JSONArray -> return value.toReadableArray()
32
+ else -> {
33
+ if (value::class.isSubclassOf(Enum::class)) {
34
+ val enumValue = value::class.memberProperties.find { x -> x.name == "value" }
35
+ if (enumValue != null) {
36
+ val rawValue = enumValue.call(value)
37
+ return getJsonRawValue(rawValue)
38
+ } else {
39
+ return value.toString()
40
+ }
41
+ } else {
42
+ return value.toReadableMap()
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ private fun WritableMap.put(key: String, value: Any?) {
49
+ when (val rawValue = getJsonRawValue(value)) {
50
+ null -> this.putNull(key)
51
+ is String -> this.putString(key, rawValue)
52
+ is Int -> this.putInt(key, rawValue)
53
+ is Double -> this.putDouble(key, rawValue)
54
+ is Boolean -> this.putBoolean(key, rawValue)
55
+ is ReadableArray -> this.putArray(key, rawValue)
56
+ is ReadableMap -> this.putMap(key, rawValue)
57
+ else -> throw IllegalArgumentException("Unsupported type: ${value!!::class.simpleName}")
58
+ }
59
+ }
60
+
61
+ private fun WritableArray.push(value: Any?) {
62
+ when (val rawValue = getJsonRawValue(value)) {
63
+ null -> this.pushNull()
64
+ is String -> this.pushString(rawValue)
65
+ is Int -> this.pushInt(rawValue)
66
+ is Double -> this.pushDouble(rawValue)
67
+ is Boolean -> this.pushBoolean(rawValue)
68
+ is ReadableArray -> this.pushArray(rawValue)
69
+ is ReadableMap -> this.pushMap(rawValue)
70
+ else -> throw IllegalArgumentException("Unsupported type: ${value!!::class.simpleName}")
71
+ }
72
+ }
73
+
74
+ fun Any?.toReadableMap(): ReadableMap? {
75
+ if (this == null) {
76
+ return null
77
+ } else {
78
+ val map = Arguments.createMap()
79
+ this::class.memberProperties.forEach { property ->
80
+ val key = property.name
81
+ val value = property.getter.call(this)
82
+ map.put(key, value)
83
+ }
84
+ return map
85
+ }
86
+ }
87
+
88
+ fun Map<*, *>.toReadableMap(): ReadableMap {
89
+ val map = Arguments.createMap()
90
+ forEach { (key, value) ->
91
+ if (key is String) {
92
+ map.put(key, value)
93
+ }
94
+ }
95
+ return map
96
+ }
97
+
98
+ fun JSONObject.toReadableMap(): ReadableMap {
99
+ val map = Arguments.createMap()
100
+
101
+ for (key in this.keys()) {
102
+ map.put(key, this.get(key))
103
+ }
104
+
105
+ return map
106
+ }
107
+
108
+ fun Collection<*>.toReadableArray(): ReadableArray {
109
+ val array = Arguments.createArray()
110
+ forEach { item ->
111
+ array.push(item)
112
+ }
113
+ return array
114
+ }
115
+
116
+ fun JSONArray.toReadableArray(): ReadableArray {
117
+ val array = Arguments.createArray()
118
+
119
+ for (index in 0..<this.length()) {
120
+ array.push(this.get(index))
121
+ }
122
+
123
+ return array
124
+ }
125
+
126
+
127
+ fun ReadableArray?.toStringArray(): Array<String>? {
128
+ return if (this != null) {
129
+ Array(this.size()) { i -> this.getString(i) ?: "" }
130
+ } else {
131
+ null
132
+ }
133
+ }
134
+
135
+ fun ReadableMap.optBoolean(key: String, defaultValue: Boolean? = false): Boolean? {
136
+ return if (this.hasKey(key) && !this.isNull(key)) {
137
+ this.getBoolean(key)
138
+ } else {
139
+ defaultValue
140
+ }
141
+ }
142
+
143
+ fun ReadableMap.optInt(key: String, defaultValue: Int? = null): Int? {
144
+ return if (this.hasKey(key) && !this.isNull(key)) {
145
+ this.getInt(key)
146
+ } else {
147
+ defaultValue
148
+ }
149
+ }
@@ -0,0 +1,7 @@
1
+ #import "generated/RNMobilyflowReactNativeSdkSpec/RNMobilyflowReactNativeSdkSpec.h"
2
+
3
+ @interface MobilyflowReactNativeSdk : NSObject <NativeMobilyflowReactNativeSdkSpec>
4
+
5
+
6
+
7
+ @end