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.
- package/.github/workflows/app_stg.yaml +203 -0
- package/.github/workflows/build.yml +2 -2
- package/.pre-commit-config.yaml +25 -0
- package/android/build.gradle +24 -13
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -1
- package/android/src/main/java/com/nami/reactlibrary/Constants.kt +1 -1
- package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +6 -50
- package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +1 -3
- package/android/src/main/java/com/nami/reactlibrary/NamiCampaignManagerBridge.kt +133 -0
- package/android/src/main/java/com/nami/reactlibrary/NamiCustomerManagerBridge.kt +89 -20
- package/android/src/main/java/com/nami/reactlibrary/NamiEmitter.kt +25 -25
- package/android/src/main/java/com/nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt +31 -130
- package/android/src/main/java/com/nami/reactlibrary/NamiMLManagerBridgeModule.kt +1 -1
- package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +36 -147
- package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +37 -39
- package/android/src/main/java/com/nami/reactlibrary/NamiUtil.kt +50 -180
- package/build-utils/get_version_code.py +140 -0
- package/index.d.ts +20 -0
- package/index.js +7 -6
- package/ios/Nami.m +18 -72
- package/ios/NamiBridgeUtil.h +4 -6
- package/ios/NamiBridgeUtil.m +37 -99
- package/ios/NamiCampaignManagerBridge.m +26 -0
- package/ios/NamiCampaignManagerBridge.swift +107 -0
- package/ios/NamiCustomerManager.m +19 -24
- package/ios/NamiCustomerManager.swift +122 -0
- package/ios/NamiEmitter.m +85 -95
- package/ios/NamiEntitlementManagerBridge.m +7 -107
- package/ios/NamiEntitlementManagerBridge.swift +74 -0
- package/ios/NamiMLManagerBridge.m +2 -2
- package/ios/NamiPaywallManagerBridge.m +22 -94
- package/ios/NamiPaywallManagerBridge.swift +93 -0
- package/ios/NamiPurchaseManagerBridge.m +40 -71
- package/ios/NamiPurchaseManagerBridge.swift +174 -0
- package/ios/Podfile +2 -2
- package/ios/RNNami-Bridging-Header.h +5 -0
- package/ios/RNNami.h +0 -1
- package/ios/RNNami.m +1 -1
- package/ios/RNNami.xcodeproj/project.pbxproj +84 -8
- package/ios/RNNami.xcodeproj/xcshareddata/xcschemes/RNNami.xcscheme +67 -0
- package/package.json +1 -1
- package/react-native-nami-sdk.podspec +3 -3
- package/src/Nami.d.ts +112 -0
- package/src/Nami.js +10 -0
- package/src/NamiCampaignManager.d.ts +54 -0
- package/src/NamiCampaignManager.js +43 -0
- package/src/NamiCustomerManager.d.ts +39 -0
- package/src/NamiCustomerManager.js +43 -0
- package/src/NamiEntitlementManager.d.ts +24 -0
- package/src/NamiEntitlementManager.js +23 -0
- package/src/NamiMLManager.d.ts +5 -0
- package/src/NamiMLManager.js +7 -0
- package/src/NamiPaywallManager.d.ts +57 -0
- package/src/NamiPaywallManager.js +28 -0
- package/src/NamiPurchaseManager.d.ts +57 -0
- package/src/NamiPurchaseManager.js +37 -0
- package/src/types.ts +36 -0
- package/android/src/main/java/com/nami/reactlibrary/NamiAnalyticsEmitter.kt +0 -121
- 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
|
|
5
|
-
import com.facebook.react.
|
|
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 "
|
|
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
|
|
67
|
-
|
|
68
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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("
|
|
141
|
+
purchaseMap.putString("skuId", skuId)
|
|
270
142
|
|
|
271
143
|
expires?.let {
|
|
272
|
-
purchaseMap.putString("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export
|
|
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";
|