@tinkerlandai/indiana-react-native 0.9.2 → 0.9.5
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/IndianaReactNative.podspec +19 -0
- package/README.md +61 -4
- package/THIRD_PARTY_NOTICES.md +74 -0
- package/android/build.gradle +24 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/ai/tinkerland/indiana/reactnative/IndianaBridgeModule.kt +237 -0
- package/android/src/main/java/ai/tinkerland/indiana/reactnative/IndianaBridgePackage.kt +11 -0
- package/dist/index.cjs +17 -1
- package/dist/index.d.cts +57408 -604
- package/dist/index.d.ts +57408 -604
- package/dist/index.js +17 -1
- package/ios/IndianaBridge.m +11 -0
- package/ios/IndianaBridge.swift +275 -0
- package/native-sdk/android/assets/indiana/index.html +268 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/BillingAuthorizationTerms.kt +55 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/BundledWebView.kt +90 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/ContentSession.kt +45 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/ContentView.kt +36 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/CustomerOperations.generated.kt +84 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/CustomerResponseSemantics.kt +193 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/CustomerSemantics.kt +120 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/CustomerSession.kt +106 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/FeatureClient.kt +65 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelCommandStorage.kt +163 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelConfigurationRelay.kt +50 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelSession.kt +208 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/FunnelView.kt +71 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/GeneratedProtocol.kt +16 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/GoogleStorefront.kt +165 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/HTTPTransport.kt +43 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/IndianaClient.kt +526 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/NativePendingKeystore.kt +81 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/NativeReceiptRelay.kt +28 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/NativeStoreOffer.kt +24 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/PaywallContent.kt +75 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/PaywallSession.kt +144 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/PaywallView.kt +74 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/Protocol.kt +28 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/PushInstallation.kt +170 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/RendererNavigation.kt +13 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/SDKVersion.kt +6 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/StoreSubscriptionManagement.kt +19 -0
- package/native-sdk/android/java/ai/tinkerland/indiana/WireSchema.kt +76 -0
- package/native-sdk/android/resources/funnel-wire-schemas.json +1 -0
- package/native-sdk/android/resources/indiana-third-party-notices.txt +101 -0
- package/native-sdk/android/resources/renderer-data-url.txt +1 -0
- package/native-sdk/ios/AnalyticsReceipt.swift +10 -0
- package/native-sdk/ios/AppleStorefront.swift +218 -0
- package/native-sdk/ios/BillingAuthorizationTerms.swift +57 -0
- package/native-sdk/ios/BundledWebView.swift +87 -0
- package/native-sdk/ios/ContentSession.swift +48 -0
- package/native-sdk/ios/ContentView.swift +51 -0
- package/native-sdk/ios/CustomerOperations.generated.swift +166 -0
- package/native-sdk/ios/CustomerResponseSemantics.swift +232 -0
- package/native-sdk/ios/CustomerSemantics.swift +145 -0
- package/native-sdk/ios/CustomerSession.swift +129 -0
- package/native-sdk/ios/FeatureClient.swift +86 -0
- package/native-sdk/ios/FunnelCommandStorage.swift +163 -0
- package/native-sdk/ios/FunnelConfigurationRelay.swift +48 -0
- package/native-sdk/ios/FunnelSession.swift +232 -0
- package/native-sdk/ios/FunnelView.swift +125 -0
- package/native-sdk/ios/GeneratedProtocol.swift +16 -0
- package/native-sdk/ios/HTTPTransport.swift +74 -0
- package/native-sdk/ios/IndianaClient.swift +601 -0
- package/native-sdk/ios/NativePendingKeychain.swift +52 -0
- package/native-sdk/ios/NativeReceiptRelay.swift +28 -0
- package/native-sdk/ios/NativeStoreOffer.swift +34 -0
- package/native-sdk/ios/PaywallContent.swift +75 -0
- package/native-sdk/ios/PaywallSession.swift +124 -0
- package/native-sdk/ios/PaywallView.swift +87 -0
- package/native-sdk/ios/Protocol.swift +49 -0
- package/native-sdk/ios/PushInstallation.swift +154 -0
- package/native-sdk/ios/RendererNavigation.swift +8 -0
- package/native-sdk/ios/Resources.swift +15 -0
- package/native-sdk/ios/SDKVersion.swift +4 -0
- package/native-sdk/ios/StoreSubscriptionManagement.swift +11 -0
- package/native-sdk/ios/WebView/THIRD_PARTY_NOTICES.txt +101 -0
- package/native-sdk/ios/WebView/index.html +268 -0
- package/native-sdk/ios/WebView/renderer-data-url.txt +1 -0
- package/native-sdk/ios/WireSchema.swift +107 -0
- package/native-sdk/ios/funnel-wire-schemas.json +1 -0
- package/package.json +8 -3
- package/react-native.config.cjs +12 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
package ai.tinkerland.indiana
|
|
2
|
+
import org.json.JSONObject
|
|
3
|
+
import org.json.JSONArray
|
|
4
|
+
import java.net.URI
|
|
5
|
+
import java.util.UUID
|
|
6
|
+
/** Generated contract interpreter for the native wire boundary; no business policy is evaluated here. */
|
|
7
|
+
internal object IndianaSchema {
|
|
8
|
+
private val schemas: JSONObject by lazy { IndianaSchema::class.java.getResourceAsStream("/funnel-wire-schemas.json")?.bufferedReader(Charsets.UTF_8)?.use { JSONObject(it.readText()) } ?: throw IndianaClientException("invalid_response") }
|
|
9
|
+
fun validate(name: String, value: JSONObject) { val root = schemas.getJSONObject(name);if (!valid(value, root, root, 0)) throw IndianaClientException("invalid_response") }
|
|
10
|
+
fun customerResponse(name: String, value: JSONObject): JSONObject { val root = schemas.getJSONObject(name); return adapt(value, root, root, listOf(name), 0) as JSONObject }
|
|
11
|
+
private fun adapt(original: Any?, schema: JSONObject, root: JSONObject, path: List<String>, depth: Int): Any? {
|
|
12
|
+
if (depth > 100) throw IndianaClientException("invalid_response")
|
|
13
|
+
if (schema.has("\$ref")) { var target: Any = root; for (part in schema.getString("\$ref").substring(2).split('/')) target = (target as JSONObject).get(part.replace("~1", "/").replace("~0", "~")); return adapt(original, target as JSONObject, root, path, depth + 1) }
|
|
14
|
+
(schema.optJSONArray("anyOf") ?: schema.optJSONArray("oneOf"))?.let { branches -> val branch = (0 until branches.length()).map { branches.getJSONObject(it) }.firstOrNull { valid(original, it, root, 0) } ?: throw IndianaClientException("invalid_response"); return adapt(original, branch, root, path, depth + 1) }
|
|
15
|
+
var value = IndianaCustomerResponseSemantics.rules(original, schema)
|
|
16
|
+
schema.optJSONArray("allOf")?.let { branches -> for (n in 0 until branches.length()) value = adapt(value, branches.getJSONObject(n), root, path, depth + 1) }
|
|
17
|
+
if (value is JSONObject) {
|
|
18
|
+
val objectValue = value as JSONObject; val properties = schema.optJSONObject("properties") ?: JSONObject()
|
|
19
|
+
for (key in properties.keys()) if (objectValue.has(key)) objectValue.put(key, adapt(objectValue.get(key), properties.getJSONObject(key), root, path + key, depth + 1))
|
|
20
|
+
schema.optJSONObject("additionalProperties")?.let { additional -> for (key in objectValue.keys()) if (!properties.has(key)) objectValue.put(key, adapt(objectValue.get(key), additional, root, path + "{}", depth + 1)) }
|
|
21
|
+
IndianaCustomerResponseSemantics.objectValue(objectValue, properties.keys().asSequence().toSet(), path); return objectValue
|
|
22
|
+
}
|
|
23
|
+
if (value is JSONArray) { val array = value as JSONArray; schema.optJSONObject("items")?.let { child -> for (n in 0 until array.length()) array.put(n, adapt(array.opt(n), child, root, path + "[]", depth + 1)) }; return array }
|
|
24
|
+
if (value is String && schema.optString("pattern") in listOf("^(0|[1-9]\\d{0,11})(\\.\\d{1,6})?$", "^-?(0|[1-9]\\d{0,11})(\\.\\d{1,6})?$")) return (value as String).toBigDecimal().stripTrailingZeros().toPlainString()
|
|
25
|
+
return value
|
|
26
|
+
}
|
|
27
|
+
internal fun equal(a: Any?, b: Any?): Boolean = when {
|
|
28
|
+
a is JSONObject && b is JSONObject -> a.keys().asSequence().toSet() == b.keys().asSequence().toSet() && a.keys().asSequence().all { equal(a.opt(it), b.opt(it)) }
|
|
29
|
+
a is JSONArray && b is JSONArray -> a.length() == b.length() && (0 until a.length()).all { equal(a.opt(it), b.opt(it)) }
|
|
30
|
+
a is Number && b is Number -> a.toDouble() == b.toDouble()
|
|
31
|
+
else -> a == b
|
|
32
|
+
}
|
|
33
|
+
private fun valid(value: Any?, schema: JSONObject, root: JSONObject, depth: Int): Boolean {
|
|
34
|
+
if (depth > 100) return false
|
|
35
|
+
val value = try { IndianaCustomerResponseSemantics.rules(value, schema) } catch (_: Exception) { return false }
|
|
36
|
+
if (schema.has("\$ref")) { val ref = schema.getString("\$ref");if (!ref.startsWith("#/")) return false;var target: Any = root;for (part in ref.substring(2).split('/')) target = (target as? JSONObject)?.opt(part.replace("~1", "/").replace("~0", "~")) ?: return false;return target is JSONObject && valid(value, target, root, depth + 1) }
|
|
37
|
+
for (name in listOf("allOf", "anyOf", "oneOf")) schema.optJSONArray(name)?.let { choices -> val matches = (0 until choices.length()).count { valid(value, choices.getJSONObject(it), root, depth + 1) };if (name == "allOf" && matches != choices.length() || name == "anyOf" && matches == 0 || name == "oneOf" && matches != 1) return false }
|
|
38
|
+
if (schema.has("const") && !equal(value, schema.opt("const"))) return false
|
|
39
|
+
schema.optJSONArray("enum")?.let { choices -> if ((0 until choices.length()).none { equal(value, choices.opt(it)) }) return false }
|
|
40
|
+
when (schema.optString("type")) {
|
|
41
|
+
"null" -> if (value != null && value != JSONObject.NULL) return false
|
|
42
|
+
"boolean" -> if (value !is Boolean) return false
|
|
43
|
+
"string" -> if (value !is String) return false
|
|
44
|
+
"number", "integer" -> if (value !is Number || !value.toDouble().isFinite() || schema.getString("type") == "integer" && value.toDouble() != kotlin.math.floor(value.toDouble())) return false
|
|
45
|
+
"object" -> if (value !is JSONObject) return false
|
|
46
|
+
"array" -> if (value !is JSONArray) return false
|
|
47
|
+
}
|
|
48
|
+
if (value is String) {
|
|
49
|
+
if (schema.has("minLength") && value.length < schema.getInt("minLength") || schema.has("maxLength") && value.length > schema.getInt("maxLength")) return false
|
|
50
|
+
if (schema.has("pattern") && !Regex(schema.getString("pattern")).containsMatchIn(value)) return false
|
|
51
|
+
try { when (schema.optString("format")) { "uuid" -> UUID.fromString(value);"date-time" -> utcMillis(value);"uri" -> if (URI(value).scheme == null) return false } } catch (_: Exception) { return false }
|
|
52
|
+
}
|
|
53
|
+
if (value is Number) {
|
|
54
|
+
val n = value.toDouble()
|
|
55
|
+
if (schema.has("minimum") && n < schema.getDouble("minimum") || schema.has("maximum") && n > schema.getDouble("maximum") || schema.has("exclusiveMinimum") && n <= schema.getDouble("exclusiveMinimum") || schema.has("exclusiveMaximum") && n >= schema.getDouble("exclusiveMaximum")) return false
|
|
56
|
+
}
|
|
57
|
+
if (value is JSONArray) {
|
|
58
|
+
if (schema.has("minItems") && value.length() < schema.getInt("minItems") || schema.has("maxItems") && value.length() > schema.getInt("maxItems")) return false
|
|
59
|
+
if (schema.optBoolean("uniqueItems")) for (index in 0 until value.length()) if ((0 until index).any { equal(value.opt(it), value.opt(index)) }) return false
|
|
60
|
+
schema.optJSONObject("items")?.let { items -> if ((0 until value.length()).any { !valid(value.opt(it), items, root, depth + 1) }) return false }
|
|
61
|
+
schema.optJSONArray("items")?.let { tuple -> for (index in 0 until value.length()) if (index < tuple.length() && !valid(value.opt(index), tuple.getJSONObject(index), root, depth + 1)) return false;if (schema.opt("additionalItems") == false && value.length() > tuple.length()) return false }
|
|
62
|
+
}
|
|
63
|
+
if (value is JSONObject) {
|
|
64
|
+
if (schema.has("maxProperties") && value.length() > schema.getInt("maxProperties") || schema.has("minProperties") && value.length() < schema.getInt("minProperties")) return false
|
|
65
|
+
val properties = schema.optJSONObject("properties") ?: JSONObject()
|
|
66
|
+
schema.optJSONArray("required")?.let { required -> if ((0 until required.length()).any { !value.has(required.getString(it)) }) return false }
|
|
67
|
+
for (key in value.keys()) {
|
|
68
|
+
if (properties.has(key)) { if (!valid(value.opt(key), properties.getJSONObject(key), root, depth + 1)) return false }
|
|
69
|
+
else if (schema.opt("additionalProperties") == false) return false
|
|
70
|
+
else schema.optJSONObject("additionalProperties")?.let { if (!valid(value.opt(key), it, root, depth + 1)) return false }
|
|
71
|
+
schema.optJSONObject("propertyNames")?.let { if (!valid(key, it, root, depth + 1)) return false }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return true
|
|
75
|
+
}
|
|
76
|
+
}
|