@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.
Files changed (83) hide show
  1. package/IndianaReactNative.podspec +19 -0
  2. package/README.md +61 -4
  3. package/THIRD_PARTY_NOTICES.md +74 -0
  4. package/android/build.gradle +24 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/java/ai/tinkerland/indiana/reactnative/IndianaBridgeModule.kt +237 -0
  7. package/android/src/main/java/ai/tinkerland/indiana/reactnative/IndianaBridgePackage.kt +11 -0
  8. package/dist/index.cjs +17 -1
  9. package/dist/index.d.cts +57408 -604
  10. package/dist/index.d.ts +57408 -604
  11. package/dist/index.js +17 -1
  12. package/ios/IndianaBridge.m +11 -0
  13. package/ios/IndianaBridge.swift +275 -0
  14. package/native-sdk/android/assets/indiana/index.html +268 -0
  15. package/native-sdk/android/java/ai/tinkerland/indiana/BillingAuthorizationTerms.kt +55 -0
  16. package/native-sdk/android/java/ai/tinkerland/indiana/BundledWebView.kt +90 -0
  17. package/native-sdk/android/java/ai/tinkerland/indiana/ContentSession.kt +45 -0
  18. package/native-sdk/android/java/ai/tinkerland/indiana/ContentView.kt +36 -0
  19. package/native-sdk/android/java/ai/tinkerland/indiana/CustomerOperations.generated.kt +84 -0
  20. package/native-sdk/android/java/ai/tinkerland/indiana/CustomerResponseSemantics.kt +193 -0
  21. package/native-sdk/android/java/ai/tinkerland/indiana/CustomerSemantics.kt +120 -0
  22. package/native-sdk/android/java/ai/tinkerland/indiana/CustomerSession.kt +106 -0
  23. package/native-sdk/android/java/ai/tinkerland/indiana/FeatureClient.kt +65 -0
  24. package/native-sdk/android/java/ai/tinkerland/indiana/FunnelCommandStorage.kt +163 -0
  25. package/native-sdk/android/java/ai/tinkerland/indiana/FunnelConfigurationRelay.kt +50 -0
  26. package/native-sdk/android/java/ai/tinkerland/indiana/FunnelSession.kt +208 -0
  27. package/native-sdk/android/java/ai/tinkerland/indiana/FunnelView.kt +71 -0
  28. package/native-sdk/android/java/ai/tinkerland/indiana/GeneratedProtocol.kt +16 -0
  29. package/native-sdk/android/java/ai/tinkerland/indiana/GoogleStorefront.kt +165 -0
  30. package/native-sdk/android/java/ai/tinkerland/indiana/HTTPTransport.kt +43 -0
  31. package/native-sdk/android/java/ai/tinkerland/indiana/IndianaClient.kt +526 -0
  32. package/native-sdk/android/java/ai/tinkerland/indiana/NativePendingKeystore.kt +81 -0
  33. package/native-sdk/android/java/ai/tinkerland/indiana/NativeReceiptRelay.kt +28 -0
  34. package/native-sdk/android/java/ai/tinkerland/indiana/NativeStoreOffer.kt +24 -0
  35. package/native-sdk/android/java/ai/tinkerland/indiana/PaywallContent.kt +75 -0
  36. package/native-sdk/android/java/ai/tinkerland/indiana/PaywallSession.kt +144 -0
  37. package/native-sdk/android/java/ai/tinkerland/indiana/PaywallView.kt +74 -0
  38. package/native-sdk/android/java/ai/tinkerland/indiana/Protocol.kt +28 -0
  39. package/native-sdk/android/java/ai/tinkerland/indiana/PushInstallation.kt +170 -0
  40. package/native-sdk/android/java/ai/tinkerland/indiana/RendererNavigation.kt +13 -0
  41. package/native-sdk/android/java/ai/tinkerland/indiana/SDKVersion.kt +6 -0
  42. package/native-sdk/android/java/ai/tinkerland/indiana/StoreSubscriptionManagement.kt +19 -0
  43. package/native-sdk/android/java/ai/tinkerland/indiana/WireSchema.kt +76 -0
  44. package/native-sdk/android/resources/funnel-wire-schemas.json +1 -0
  45. package/native-sdk/android/resources/indiana-third-party-notices.txt +101 -0
  46. package/native-sdk/android/resources/renderer-data-url.txt +1 -0
  47. package/native-sdk/ios/AnalyticsReceipt.swift +10 -0
  48. package/native-sdk/ios/AppleStorefront.swift +218 -0
  49. package/native-sdk/ios/BillingAuthorizationTerms.swift +57 -0
  50. package/native-sdk/ios/BundledWebView.swift +87 -0
  51. package/native-sdk/ios/ContentSession.swift +48 -0
  52. package/native-sdk/ios/ContentView.swift +51 -0
  53. package/native-sdk/ios/CustomerOperations.generated.swift +166 -0
  54. package/native-sdk/ios/CustomerResponseSemantics.swift +232 -0
  55. package/native-sdk/ios/CustomerSemantics.swift +145 -0
  56. package/native-sdk/ios/CustomerSession.swift +129 -0
  57. package/native-sdk/ios/FeatureClient.swift +86 -0
  58. package/native-sdk/ios/FunnelCommandStorage.swift +163 -0
  59. package/native-sdk/ios/FunnelConfigurationRelay.swift +48 -0
  60. package/native-sdk/ios/FunnelSession.swift +232 -0
  61. package/native-sdk/ios/FunnelView.swift +125 -0
  62. package/native-sdk/ios/GeneratedProtocol.swift +16 -0
  63. package/native-sdk/ios/HTTPTransport.swift +74 -0
  64. package/native-sdk/ios/IndianaClient.swift +601 -0
  65. package/native-sdk/ios/NativePendingKeychain.swift +52 -0
  66. package/native-sdk/ios/NativeReceiptRelay.swift +28 -0
  67. package/native-sdk/ios/NativeStoreOffer.swift +34 -0
  68. package/native-sdk/ios/PaywallContent.swift +75 -0
  69. package/native-sdk/ios/PaywallSession.swift +124 -0
  70. package/native-sdk/ios/PaywallView.swift +87 -0
  71. package/native-sdk/ios/Protocol.swift +49 -0
  72. package/native-sdk/ios/PushInstallation.swift +154 -0
  73. package/native-sdk/ios/RendererNavigation.swift +8 -0
  74. package/native-sdk/ios/Resources.swift +15 -0
  75. package/native-sdk/ios/SDKVersion.swift +4 -0
  76. package/native-sdk/ios/StoreSubscriptionManagement.swift +11 -0
  77. package/native-sdk/ios/WebView/THIRD_PARTY_NOTICES.txt +101 -0
  78. package/native-sdk/ios/WebView/index.html +268 -0
  79. package/native-sdk/ios/WebView/renderer-data-url.txt +1 -0
  80. package/native-sdk/ios/WireSchema.swift +107 -0
  81. package/native-sdk/ios/funnel-wire-schemas.json +1 -0
  82. package/package.json +8 -3
  83. 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
+ }