react-native-nami-sdk 2.0.4 → 3.0.8

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 (59) hide show
  1. package/.github/workflows/app_stg.yaml +203 -0
  2. package/.github/workflows/build.yml +2 -2
  3. package/.pre-commit-config.yaml +25 -0
  4. package/android/build.gradle +24 -13
  5. package/android/gradle/wrapper/gradle-wrapper.properties +5 -1
  6. package/android/src/main/java/com/nami/reactlibrary/Constants.kt +1 -1
  7. package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +6 -50
  8. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +1 -3
  9. package/android/src/main/java/com/nami/reactlibrary/NamiCampaignManagerBridge.kt +133 -0
  10. package/android/src/main/java/com/nami/reactlibrary/NamiCustomerManagerBridge.kt +89 -20
  11. package/android/src/main/java/com/nami/reactlibrary/NamiEmitter.kt +25 -25
  12. package/android/src/main/java/com/nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt +31 -130
  13. package/android/src/main/java/com/nami/reactlibrary/NamiMLManagerBridgeModule.kt +1 -1
  14. package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +36 -147
  15. package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +37 -39
  16. package/android/src/main/java/com/nami/reactlibrary/NamiUtil.kt +50 -180
  17. package/build-utils/get_version_code.py +140 -0
  18. package/index.d.ts +20 -0
  19. package/index.js +7 -6
  20. package/ios/Nami.m +18 -72
  21. package/ios/NamiBridgeUtil.h +4 -6
  22. package/ios/NamiBridgeUtil.m +37 -99
  23. package/ios/NamiCampaignManagerBridge.m +26 -0
  24. package/ios/NamiCampaignManagerBridge.swift +107 -0
  25. package/ios/NamiCustomerManager.m +19 -24
  26. package/ios/NamiCustomerManager.swift +122 -0
  27. package/ios/NamiEmitter.m +85 -95
  28. package/ios/NamiEntitlementManagerBridge.m +7 -107
  29. package/ios/NamiEntitlementManagerBridge.swift +74 -0
  30. package/ios/NamiMLManagerBridge.m +2 -2
  31. package/ios/NamiPaywallManagerBridge.m +22 -94
  32. package/ios/NamiPaywallManagerBridge.swift +93 -0
  33. package/ios/NamiPurchaseManagerBridge.m +40 -71
  34. package/ios/NamiPurchaseManagerBridge.swift +174 -0
  35. package/ios/Podfile +2 -2
  36. package/ios/RNNami-Bridging-Header.h +5 -0
  37. package/ios/RNNami.h +0 -1
  38. package/ios/RNNami.m +1 -1
  39. package/ios/RNNami.xcodeproj/project.pbxproj +84 -8
  40. package/ios/RNNami.xcodeproj/xcshareddata/xcschemes/RNNami.xcscheme +67 -0
  41. package/package.json +1 -1
  42. package/react-native-nami-sdk.podspec +3 -3
  43. package/src/Nami.d.ts +112 -0
  44. package/src/Nami.js +10 -0
  45. package/src/NamiCampaignManager.d.ts +54 -0
  46. package/src/NamiCampaignManager.js +43 -0
  47. package/src/NamiCustomerManager.d.ts +39 -0
  48. package/src/NamiCustomerManager.js +43 -0
  49. package/src/NamiEntitlementManager.d.ts +24 -0
  50. package/src/NamiEntitlementManager.js +23 -0
  51. package/src/NamiMLManager.d.ts +5 -0
  52. package/src/NamiMLManager.js +7 -0
  53. package/src/NamiPaywallManager.d.ts +57 -0
  54. package/src/NamiPaywallManager.js +28 -0
  55. package/src/NamiPurchaseManager.d.ts +57 -0
  56. package/src/NamiPurchaseManager.js +37 -0
  57. package/src/types.ts +36 -0
  58. package/android/src/main/java/com/nami/reactlibrary/NamiAnalyticsEmitter.kt +0 -121
  59. package/ios/NamiAnalyticsEmitter.m +0 -146
@@ -1,22 +1,16 @@
1
1
  package com.nami.reactlibrary
2
2
 
3
3
  import android.util.Log
4
- import com.facebook.react.bridge.Callback
5
- import com.facebook.react.bridge.ReactApplicationContext
6
- import com.facebook.react.bridge.ReactContextBaseJavaModule
7
- import com.facebook.react.bridge.ReactMethod
8
- import com.facebook.react.bridge.ReadableArray
9
- import com.facebook.react.bridge.ReadableType
10
- import com.facebook.react.bridge.WritableArray
11
- import com.facebook.react.bridge.WritableNativeArray
12
- import com.facebook.react.bridge.WritableNativeMap
4
+ import com.facebook.react.bridge.*
5
+ import com.facebook.react.modules.core.DeviceEventManagerModule
13
6
  import com.namiml.billing.NamiPurchaseManager
7
+ import com.namiml.paywall.NamiPaywallManager
14
8
 
15
9
  class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
16
10
  ReactContextBaseJavaModule(reactContext) {
17
11
 
18
12
  override fun getName(): String {
19
- return "NamiPurchaseManagerBridge"
13
+ return "RNNamiPurchaseManager"
20
14
  }
21
15
 
22
16
  @ReactMethod
@@ -26,26 +20,6 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
26
20
  }
27
21
  }
28
22
 
29
- @ReactMethod
30
- fun buySKU(skuPlatformID: String, developerPaywallID: String, resultsCallback: Callback) {
31
- reactApplicationContext.runOnUiQueueThread {
32
- currentActivity?.let {
33
- NamiPurchaseManager.buySKU(it, skuPlatformID) {
34
-
35
- val result: Boolean
36
- if (NamiPurchaseManager.isSKUIDPurchased(skuPlatformID)) {
37
- result = true
38
- Log.i(LOG_TAG, "Purchase complete, result is PURCHASED.")
39
- } else {
40
- result = false
41
- Log.i(LOG_TAG, "Purchase complete, product not purchased.")
42
- }
43
- resultsCallback.invoke(result)
44
- }
45
- }
46
- }
47
- }
48
-
49
23
  @ReactMethod
50
24
  fun purchases(resultsCallback: Callback) {
51
25
  reactApplicationContext.runOnUiQueueThread {
@@ -63,22 +37,20 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
63
37
  }
64
38
 
65
39
  @ReactMethod
66
- fun isSKUIDPurchased(skuID: String, resultsCallback: Callback) {
67
- reactApplicationContext.runOnUiQueueThread {
68
- val isPurchased = NamiPurchaseManager.isSKUIDPurchased(skuID)
69
- resultsCallback.invoke(isPurchased)
70
- }
40
+ fun skuPurchased(skuID: String, promise: Promise) {
41
+ val isPurchased = NamiPurchaseManager.isSKUIDPurchased(skuID)
42
+ promise.resolve(isPurchased)
71
43
  }
72
44
 
73
45
  @ReactMethod
74
- fun consumePurchasedSKU(skuRefId: String) {
46
+ fun consumePurchasedSku(skuRefId: String) {
75
47
  reactApplicationContext.runOnUiQueueThread {
76
48
  NamiPurchaseManager.consumePurchasedSKU(skuRefId)
77
49
  }
78
50
  }
79
51
 
80
52
  @ReactMethod
81
- fun anySKUIDPurchased(skuIDs: ReadableArray, resultsCallback: Callback) {
53
+ fun anySkuPurchased(skuIDs: ReadableArray, promise: Promise) {
82
54
  reactApplicationContext.runOnUiQueueThread {
83
55
  val checkArray: MutableList<String> = mutableListOf()
84
56
  for (x in 0 until skuIDs.size()) {
@@ -92,7 +64,7 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
92
64
 
93
65
  val anyPurchased = NamiPurchaseManager.anySKUIDPurchased(checkArray)
94
66
 
95
- resultsCallback.invoke(anyPurchased)
67
+ promise.resolve(anyPurchased)
96
68
  }
97
69
  }
98
70
 
@@ -109,4 +81,30 @@ class NamiPurchaseManagerBridgeModule(reactContext: ReactApplicationContext) :
109
81
  }
110
82
  resultsCallback.invoke(resultMap)
111
83
  }
112
- }
84
+
85
+ @ReactMethod
86
+ fun registerPurchasesChangedHandler() {
87
+ NamiPurchaseManager.registerPurchasesChangedHandler{purchases, purchaseState, error ->
88
+ run {
89
+ val resultPurchases: WritableArray = WritableNativeArray()
90
+
91
+ for (purchase in purchases) {
92
+ resultPurchases.pushMap(purchase.toPurchaseDict())
93
+ }
94
+
95
+ val stateString = purchaseState.toString()
96
+
97
+ val payload = Arguments.createMap()
98
+ payload.putArray("purchases", resultPurchases)
99
+ payload.putString("purchaseState", stateString)
100
+ payload.putString("error", error)
101
+
102
+ reactApplicationContext
103
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
104
+ .emit("PurchasesChanged", payload)
105
+
106
+
107
+ }
108
+ }
109
+ }
110
+ }
@@ -14,8 +14,6 @@ import com.namiml.paywall.NamiLocaleConfig
14
14
  import com.namiml.paywall.NamiPaywall
15
15
  import com.namiml.paywall.NamiPurchaseSource
16
16
  import com.namiml.paywall.NamiSKU
17
- import com.namiml.paywall.PaywallDisplayOptions
18
- import com.namiml.paywall.PaywallStyleData
19
17
  import com.namiml.paywall.SubscriptionPeriod
20
18
  import com.namiml.util.extensions.getFormattedPrice
21
19
  import com.namiml.util.extensions.getSubscriptionPeriodEnum
@@ -25,125 +23,6 @@ import java.util.Date
25
23
  import java.util.Locale
26
24
  import java.util.TimeZone
27
25
 
28
- fun NamiPaywall.toNamiPaywallDict(): WritableMap {
29
-
30
- val paywallMap: WritableMap = Arguments.createMap()
31
-
32
- val marketingContentMap = Arguments.createMap()
33
- marketingContentMap.putString("title", title.orEmpty())
34
- marketingContentMap.putString("body", body.orEmpty())
35
-
36
- val extraDataMap = extraData
37
- if (extraDataMap != null) {
38
- marketingContentMap.putMap("extra_data", extraDataMap.toWritableMap())
39
- }
40
-
41
- paywallMap.putMap("marketing_content", marketingContentMap)
42
-
43
- Log.i(LOG_TAG, "extraData items are $extraDataMap")
44
- paywallMap.putString("id", id)
45
- paywallMap.putMap("backgrounds", Arguments.createMap().apply {
46
- putString("phone", backgroundImageUrlPhone.orEmpty())
47
- putString("tablet", backgroundImageUrlTablet.orEmpty())
48
- })
49
- paywallMap.putString("purchase_terms", purchaseTerms.orEmpty())
50
- paywallMap.putString("name", name.orEmpty())
51
- paywallMap.putString("paywall_type", type)
52
- paywallMap.putMap("locale_config", localeConfig.toDict())
53
- paywallMap.putMap("legal_citations", legalCitations?.toDict())
54
- paywallMap.putMap("display_options", displayOptions.toDict())
55
- paywallMap.putString("developer_paywall_id", developerPaywallId.orEmpty())
56
- styleData?.let {
57
- paywallMap.putMap("styleData", it.toPaywallStylingDict())
58
- }
59
- return paywallMap
60
- }
61
-
62
- private fun NamiLocaleConfig.toDict(): WritableMap {
63
- return Arguments.createMap().apply {
64
- putString("close_button_text", closeButtonText)
65
- putString("sign_in_button_text", signInButtonText)
66
- putString("restore_purchase_button_text", restorePurchaseButtonText)
67
- putString("purchase_button_hint_text_to_speech", purchaseButtonHintTextToSpeech)
68
- putString("purchase_terms_prefix_hint_text_to_speech", purchaseTermsPrefixHintTextToSpeech)
69
- }
70
- }
71
-
72
- private fun PaywallDisplayOptions.toDict(): WritableMap {
73
- return Arguments.createMap().apply {
74
- putBoolean("allow_closing", allowClosing)
75
- putBoolean("restore_control", restoreControl)
76
- putBoolean("sign_in_control", signInControl)
77
- putString("scrollable_region_size", scrollableRegionSize)
78
- putBoolean("show_nami_purchase_success_message", shouldShowNamiPurchaseSuccessMessage)
79
- putBoolean("skus_in_scrollable_region", showSkusInScrollableRegion)
80
- putBoolean("use_bottom_overlay", useBottomOverlay)
81
- }
82
- }
83
-
84
- private fun LegalCitations.toDict(): WritableMap {
85
- return Arguments.createMap().apply {
86
- putString("id", id)
87
- putString("privacy_url", privacyUrl)
88
- putString("privacy_text", privacyText)
89
- putString("tos_url", tosUrl)
90
- putString("tos_text", tosText)
91
- putString("clickwrap_text", clickWrapText)
92
- putString("language", language)
93
- }
94
- }
95
-
96
- fun PaywallStyleData.toPaywallStylingDict(): WritableMap {
97
-
98
- val styleMap: WritableMap = Arguments.createMap()
99
- styleMap.putString("backgroundColor", backgroundColor)
100
-
101
- styleMap.putDouble("bodyFontSize", bodyFontSize.toDouble())
102
- styleMap.putString("bodyTextColor", bodyTextColor)
103
- styleMap.putString("bodyShadowColor", bodyShadowColor)
104
- styleMap.putDouble("bodyShadowRadius", bodyShadowRadius.toDouble())
105
-
106
- styleMap.putDouble("titleFontSize", titleFontSize.toDouble())
107
- styleMap.putString("titleTextColor", titleTextColor)
108
- styleMap.putString("titleShadowColor", titleShadowColor)
109
- styleMap.putDouble("titleShadowRadius", titleShadowRadius.toDouble())
110
-
111
- styleMap.putDouble("closeButtonFontSize", closeButtonFontSize.toDouble())
112
- styleMap.putString("closeButtonTextColor", closeButtonTextColor)
113
- styleMap.putString("closeButtonShadowColor", closeButtonShadowColor)
114
- styleMap.putDouble("closeButtonShadowRadius", closeButtonShadowRadius.toDouble())
115
-
116
- styleMap.putString("bottomOverlayColor", bottomOverlayColor)
117
- styleMap.putDouble("bottomOverlayCornerRadius", bottomOverlayCornerRadius.toDouble())
118
-
119
- styleMap.putString("skuButtonColor", skuButtonColor)
120
- styleMap.putString("skuButtonTextColor", skuButtonTextColor)
121
- styleMap.putString("skuSubDisplayTextColor", skuSubDisplayTextColor)
122
- styleMap.putString("skuSubDisplayTextShadowColor", skuSubDisplayTextShadowColor)
123
- styleMap.putDouble("skuSubDisplayTextShadowRadius", skuSubDisplayTextShadowRadius.toDouble())
124
-
125
- styleMap.putString("featuredSkusButtonColor", featuredSkuButtonColor)
126
- styleMap.putString("featuredSkusButtonTextColor", featuredSkuButtonTextColor)
127
-
128
- styleMap.putDouble("signinButtonFontSize", signInButtonFontSize.toDouble())
129
- styleMap.putString("signinButtonTextColor", signInButtonTextColor)
130
- styleMap.putString("signinButtonShadowColor", signInButtonShadowColor)
131
- styleMap.putDouble("signinButtonShadowRadius", signInButtonShadowRadius.toDouble())
132
-
133
- styleMap.putDouble("restoreButtonFontSize", restoreButtonFontSize.toDouble())
134
- styleMap.putString("restoreButtonTextColor", restoreButtonTextColor)
135
- styleMap.putString("restoreButtonShadowColor", restoreButtonShadowColor)
136
- styleMap.putDouble("restoreButtonShadowRadius", restoreButtonShadowRadius.toDouble())
137
-
138
- styleMap.putDouble("purchaseTermsFontSize", purchaseTermsFontSize.toDouble())
139
- styleMap.putString("purchaseTermsTextColor", purchaseTermsTextColor)
140
- styleMap.putString("purchaseTermsShadowColor", purchaseTermsShadowColor)
141
- styleMap.putDouble("purchaseTermsShadowRadius", purchaseTermsShadowRadius.toDouble())
142
-
143
- styleMap.putString("termsLinkColor", termsLinkColor)
144
-
145
- return styleMap
146
- }
147
26
 
148
27
  fun List<*>.toWritableArray(): WritableArray {
149
28
  val convertedArray = Arguments.createArray()
@@ -206,44 +85,44 @@ fun NamiSKU.toSkuDict(): WritableMap {
206
85
  val productDict = Arguments.createMap()
207
86
 
208
87
  productDict.putString("skuIdentifier", skuId)
209
- productDict.putString("localizedTitle", skuDetails.title)
210
- productDict.putString("localizedDescription", skuDetails.description)
211
- productDict.putString("localizedPrice", skuDetails.price)
212
- productDict.putString("localizedMultipliedPrice", skuDetails.price)
88
+ // productDict.putString("localizedTitle", skuDetails.title)
89
+ // productDict.putString("localizedDescription", skuDetails.description)
90
+ // productDict.putString("localizedPrice", skuDetails.price)
91
+ // productDict.putString("localizedMultipliedPrice", skuDetails.price)
213
92
  productDict.putBoolean("featured", featured)
214
- productDict.putString("displayText", displayText)
215
- productDict.putString("displaySubText", displaySubText)
216
- productDict.putString("price", skuDetails.getFormattedPrice().toString())
93
+ // productDict.putString("displayText", displayText)
94
+ // productDict.putString("displaySubText", displaySubText)
95
+ // productDict.putString("price", skuDetails.getFormattedPrice().toString())
217
96
  productDict.putString("priceLanguage", Locale.getDefault().language)
218
97
  productDict.putString("priceCountry", Locale.getDefault().country)
219
- productDict.putString("priceCurrency", skuDetails.priceCurrencyCode)
98
+ // productDict.putString("priceCurrency", skuDetails.priceCurrencyCode)
220
99
  productDict.putString("numberOfUnits", "1")
221
- val subscriptionPeriod = when (skuDetails.getSubscriptionPeriodEnum()) {
222
- SubscriptionPeriod.MONTHLY -> {
223
- "month"
224
- }
225
- SubscriptionPeriod.HALF_YEAR -> {
226
- "half_year"
227
- }
228
- SubscriptionPeriod.WEEKLY -> {
229
- "week"
230
- }
231
- SubscriptionPeriod.QUARTERLY -> {
232
- "quarter"
233
- }
234
- SubscriptionPeriod.ANNUAL -> {
235
- "year"
236
- }
237
- SubscriptionPeriod.FOUR_WEEKS -> {
238
- "four_weeks"
239
- }
240
- else -> {
241
- null
242
- }
243
- }
244
- if (subscriptionPeriod != null) {
245
- productDict.putString("periodUnit", subscriptionPeriod)
246
- }
100
+ // val subscriptionPeriod = when (skuDetails.getSubscriptionPeriodEnum()) {
101
+ // SubscriptionPeriod.MONTHLY -> {
102
+ // "month"
103
+ // }
104
+ // SubscriptionPeriod.HALF_YEAR -> {
105
+ // "half_year"
106
+ // }
107
+ // SubscriptionPeriod.WEEKLY -> {
108
+ // "week"
109
+ // }
110
+ // SubscriptionPeriod.QUARTERLY -> {
111
+ // "quarter"
112
+ // }
113
+ // SubscriptionPeriod.ANNUAL -> {
114
+ // "year"
115
+ // }
116
+ // SubscriptionPeriod.FOUR_WEEKS -> {
117
+ // "four_weeks"
118
+ // }
119
+ // else -> {
120
+ // null
121
+ // }
122
+ // }
123
+ // if (subscriptionPeriod != null) {
124
+ // productDict.putString("periodUnit", subscriptionPeriod)
125
+ // }
247
126
 
248
127
  return productDict
249
128
  }
@@ -252,32 +131,23 @@ fun NamiSKU.toSkuDict(): WritableMap {
252
131
  fun NamiPurchase.toPurchaseDict(): WritableMap {
253
132
  val purchaseMap = WritableNativeMap()
254
133
 
255
- val purchaseSource = when (purchaseSource) {
256
- NamiPurchaseSource.NAMI_PAYWALL -> {
257
- "nami_rules"
258
- }
259
- NamiPurchaseSource.APPLICATION -> {
260
- "user"
261
- }
262
- else -> {
263
- "unknown"
264
- }
265
- }
134
+ val purchaseSource = purchaseSource.toString()
266
135
  purchaseMap.putString("purchaseSource", purchaseSource)
267
136
 
137
+ val skuDict = namiSku?.toSkuDict()
138
+ purchaseMap.putMap("sku", skuDict)
139
+
268
140
  purchaseMap.putString("transactionIdentifier", transactionIdentifier.orEmpty())
269
- purchaseMap.putString("skuIdentifier", skuId)
141
+ purchaseMap.putString("skuId", skuId)
270
142
 
271
143
  expires?.let {
272
- purchaseMap.putString("subscriptionExpirationDate", it.toJavascriptDate())
144
+ purchaseMap.putString("expires", it.toJavascriptDate())
145
+ }
146
+ val initiatedTimestamp = purchaseInitiatedTimestamp
147
+ val purchaseInitiatedDate = Date(initiatedTimestamp)
148
+ purchaseInitiatedDate.let {
149
+ purchaseMap.putString("purchaseInitiatedTimestamp", it.toJavascriptDate())
273
150
  }
274
-
275
- // Removed, not sure why, should add back in when possible
276
- // val initiatedTimestamp = purchase.purchaseInitiatedTimestamp
277
- // val dt = Instant.ofEpochSecond(initiatedTimestamp)
278
- // .atZone(ZoneId.systemDefault())
279
- // .toLocalDateTime()
280
- // purchaseMap.putString("purchaseInitiatedTimestamp", purchase.purchaseInitiatedTimestamp ?: "")
281
151
 
282
152
  // TODO: map kotlin dictionary into arbitrary map?
283
153
  purchaseMap.putMap("platformMetadata", WritableNativeMap())
@@ -307,7 +177,7 @@ fun CustomerJourneyState?.toDict(): WritableMap {
307
177
 
308
178
  fun NamiEntitlement.toEntitlementDict(): WritableMap? {
309
179
  val resultMap: WritableMap = WritableNativeMap()
310
- resultMap.putString("referenceID", referenceId)
180
+ resultMap.putString("referenceId", referenceId)
311
181
 
312
182
  Log.i(LOG_TAG, "Processing entitlement into Javascript Map with referenceID $referenceId")
313
183
 
@@ -316,7 +186,7 @@ fun NamiEntitlement.toEntitlementDict(): WritableMap? {
316
186
  return null
317
187
  }
318
188
 
319
- resultMap.putString("namiID", namiId.orEmpty())
189
+ resultMap.putString("namiId", namiId.orEmpty())
320
190
  resultMap.putString("desc", desc.orEmpty())
321
191
  resultMap.putString("name", name.orEmpty())
322
192
 
@@ -330,13 +200,13 @@ fun NamiEntitlement.toEntitlementDict(): WritableMap? {
330
200
  for (sku in purchasedSKUs) {
331
201
  purchasedSKUsArray.pushMap(sku.toSkuDict())
332
202
  }
333
- resultMap.putArray("purchasedSKUs", purchasedSKUsArray)
203
+ resultMap.putArray("purchasedSkus", purchasedSKUsArray)
334
204
 
335
205
  val relatedSKUsArray: WritableArray = WritableNativeArray()
336
206
  for (sku in relatedSKUs) {
337
207
  relatedSKUsArray.pushMap(sku.toSkuDict())
338
208
  }
339
- resultMap.putArray("relatedSKUs", relatedSKUsArray)
209
+ resultMap.putArray("relatedSkus", relatedSKUsArray)
340
210
 
341
211
  // For react, provide the most recent active purchase and sku from the arrays
342
212
 
@@ -354,7 +224,7 @@ fun NamiEntitlement.toEntitlementDict(): WritableMap? {
354
224
 
355
225
  // Convert Java Date to ISO860 UTC date to pass to Javascript
356
226
  fun Date.toJavascriptDate(): String {
357
- val df: DateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.getDefault()).apply {
227
+ val df: DateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault()).apply {
358
228
  timeZone = TimeZone.getTimeZone("UTC")
359
229
  }
360
230
  return df.format(this)
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/python3
2
+
3
+ import sys
4
+ import getopt
5
+ import json
6
+
7
+ from google.auth.exceptions import DefaultCredentialsError
8
+ from google.oauth2 import service_account
9
+ from googleapiclient import discovery, errors
10
+
11
+ from pyasn1.error import SubstrateUnderrunError
12
+
13
+ def printv(text):
14
+ if show_output:
15
+ print(text)
16
+
17
+ def create_edit(service, package_name):
18
+ printv(f"Create an edit for the package {package_name}")
19
+ try:
20
+ edit_request = service.edits().insert(body={}, packageName=package_name)
21
+ edit_response = edit_request.execute()
22
+ printv(f"Created edit {edit_response} for package {package_name}")
23
+ except (errors.Error, errors.HttpError) as e:
24
+ raise(f"Error creating edit {e}")
25
+ else:
26
+ if "id" in edit_response:
27
+ return edit_response["id"]
28
+
29
+ def delete_edit(service, package_name, edit_id):
30
+ printv(f"Delete an edit for the package {package_name}")
31
+ try:
32
+ delete_request = service.edits().delete(packageName=package_name, editId=edit_id)
33
+ delete_response = delete_request.execute()
34
+ printv(f"Deleted edit {delete_response} for package {package_name}")
35
+ except (errors.Error, errors.HttpError) as e:
36
+ raise(f"Error deleting edit {e}")
37
+
38
+ def get_credentials_response(service_credentials_path):
39
+ try:
40
+ credentials_response = service_account.Credentials.from_service_account_file(
41
+ service_credentials_path)
42
+ except ValueError as error:
43
+ printv(f"401: {error}")
44
+ return None
45
+ except DefaultCredentialsError as error:
46
+ printv(f"401: {error}")
47
+ return None
48
+ except SubstrateUnderrunError as error:
49
+ printv(f"401: The service credentials are malformed")
50
+ return None
51
+
52
+ if type(credentials_response) is service_account.Credentials:
53
+ return credentials_response
54
+ else:
55
+ printv(f"401: Unknown error with service account credentials.")
56
+ return None
57
+
58
+ def get_track(service, package_name, edit_id, track_name):
59
+ request = (
60
+ service.edits().tracks()
61
+ .get(packageName=package_name, editId=edit_id, track=track_name)
62
+ )
63
+ try:
64
+ response = request.execute()
65
+ except errors.HttpError as error:
66
+ error_content = json.loads(error.content)
67
+ if "error" in error_content:
68
+ error = error_content["error"]
69
+
70
+ if "code" in error:
71
+ status_code = error["code"]
72
+ else:
73
+ status_code = 000
74
+
75
+ if "message" in error:
76
+ message = error["message"]
77
+ else:
78
+ message = "Unknown error"
79
+
80
+ printv(f"{status_code}: {message}")
81
+ else:
82
+ printv(f"200: API request was successful")
83
+ printv(response)
84
+ version_codes = []
85
+ if "releases" in response:
86
+ releases = response["releases"]
87
+ for release in releases:
88
+ if "versionCodes" in release:
89
+ all_codes = release["versionCodes"]
90
+ for code in all_codes:
91
+ printv(code)
92
+ if code in version_codes:
93
+ pass
94
+ else:
95
+ version_codes.append(int(code))
96
+
97
+ printv(f"observed codes: {version_codes}")
98
+ new_version = max(version_codes)+1
99
+ print(f"{new_version}")
100
+ with open(".new_version_code", "w") as f:
101
+ f.write(
102
+ f"{new_version}"
103
+ )
104
+
105
+ def get_version_code(service_credentials_path, package_name, track_name):
106
+ credentials = get_credentials_response(service_credentials_path)
107
+
108
+ service = discovery.build(
109
+ "androidpublisher", "v3", credentials=credentials, cache_discovery=False
110
+ )
111
+
112
+ edit_id = create_edit(service, package_name)
113
+ get_track(service, package_name, edit_id, track_name)
114
+ delete_edit(service, package_name, edit_id)
115
+
116
+ if __name__ == "__main__":
117
+ help_message = "get_version_code.py /path/to/service_credentials.json [package_name] [track_name] <OPTIONAL: --quiet>"
118
+
119
+ if len(sys.argv) < 4:
120
+ print(help_message)
121
+ sys.exit(2)
122
+
123
+ service_credentials = sys.argv[1]
124
+
125
+ package_name = sys.argv[2]
126
+ track_name = sys.argv[3]
127
+
128
+ show_output = True
129
+
130
+ try:
131
+ opts, args = getopt.getopt(sys.argv[4:], "", ["quiet"])
132
+ except getopt.GetoptError:
133
+ print(help_message)
134
+ sys.exit(2)
135
+
136
+ for opt, arg in opts:
137
+ if opt in ("--quiet"):
138
+ show_output = False
139
+
140
+ get_version_code(service_credentials, package_name, track_name)
package/index.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export { Nami, NamiConfiguration, NamiLanguageCodes } from "./src/Nami";
2
+ export { NamiMLManager } from "./src/NamiMLManager";
3
+ export {
4
+ NamiCampaignManager,
5
+ NamiCampaign,
6
+ NamiCampaignRuleType,
7
+ LaunchCampaignError,
8
+ } from "./src/NamiCampaignManager";
9
+ export {
10
+ NamiCustomerManager,
11
+ CustomerJourneyState,
12
+ AccountStateAction,
13
+ } from "./src/NamiCustomerManager";
14
+ export {
15
+ NamiEntitlementManager,
16
+ NamiEntitlement,
17
+ } from "./src/NamiEntitlementManager";
18
+ export { NamiPurchaseManager, NamiPurchase } from "./src/NamiPurchaseManager";
19
+ export { NamiPaywallManager } from "./src/NamiPaywallManager";
20
+ export { NamiSKU } from "./src/types";
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
-
2
- import { NativeModules } from 'react-native';
3
-
4
- const { RNNami } = NativeModules;
5
-
6
- export default RNNami;
1
+ export { Nami } from "./src/Nami";
2
+ export { NamiMLManager } from "./src/NamiMLManager";
3
+ export { NamiCampaignManager } from "./src/NamiCampaignManager";
4
+ export { NamiCustomerManager } from "./src/NamiCustomerManager";
5
+ export { NamiEntitlementManager } from "./src/NamiEntitlementManager";
6
+ export { NamiPurchaseManager } from "./src/NamiPurchaseManager";
7
+ export { NamiPaywallManager } from "./src/NamiPaywallManager";