@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,74 @@
1
+ import Foundation
2
+
3
+ public struct IndianaConfiguration: Sendable {
4
+ public let baseURL: URL
5
+ internal var apiOrigin: String {
6
+ var parts = URLComponents(url: baseURL, resolvingAgainstBaseURL: true)!
7
+ parts.path = ""; parts.query = nil; parts.fragment = nil
8
+ parts.host = parts.host?.lowercased(); if parts.port == 443 { parts.port = nil }
9
+ return parts.string!
10
+ }
11
+ public let scope: IndianaScope
12
+ public let timeout: TimeInterval
13
+ /// Override baseURL explicitly for test services; Sandbox is a business scope, not a deployment selector.
14
+ public init(baseURL: URL = URL(string: "https://api.tinker.cash")!, scope: IndianaScope, timeout: TimeInterval = 15) throws {
15
+ guard baseURL.scheme == "https", baseURL.host != nil, baseURL.user == nil, baseURL.password == nil,
16
+ baseURL.query == nil, baseURL.fragment == nil, timeout > 0, timeout <= 120 else { throw IndianaClientError.invalidConfiguration }
17
+ self.baseURL = baseURL; self.scope = scope; self.timeout = timeout
18
+ }
19
+ }
20
+ protocol IndianaHTTP: Sendable {
21
+ func send(path: String, method: String, authorization: String, body: Data?) async throws -> Data
22
+ }
23
+ final class IndianaURLTransport: IndianaHTTP, Sendable {
24
+ static func requireCurrentProtocol(_ value: String?) throws {
25
+ guard value == IndianaProtocol.wireProtocol else { throw IndianaClientError.invalidResponse }
26
+ }
27
+ private let configuration: IndianaConfiguration
28
+ private let requestOrigin: URL
29
+ private let session: URLSession
30
+ // Internal test seam: the public configuration remains HTTPS-only. A wire fixture
31
+ // may use only a loopback HTTP origin; no public SDK caller can select it.
32
+ init(configuration: IndianaConfiguration, sessionConfiguration: URLSessionConfiguration = .ephemeral, loopbackFixtureOrigin: URL? = nil) {
33
+ self.configuration = configuration
34
+ if let origin = loopbackFixtureOrigin {
35
+ precondition(origin.scheme == "http" && origin.host == "127.0.0.1" && (origin.port ?? 0) > 1024 && origin.user == nil && origin.password == nil && origin.query == nil && origin.fragment == nil && origin.path.isEmpty)
36
+ }
37
+ self.requestOrigin = loopbackFixtureOrigin ?? configuration.baseURL
38
+ let config = sessionConfiguration.copy() as! URLSessionConfiguration
39
+ config.urlCache = nil; config.httpCookieStorage = nil; config.httpShouldSetCookies = false; config.urlCredentialStorage = nil; config.requestCachePolicy = .reloadIgnoringLocalCacheData
40
+ let ownedHeaders = Set(["authorization", "cookie", "x-indiana-project", "x-indiana-environment", "x-indiana-protocol", "x-indiana-sdk-version"])
41
+ config.httpAdditionalHeaders = config.httpAdditionalHeaders?.filter { !ownedHeaders.contains(String(describing: $0.key).lowercased()) }
42
+ config.timeoutIntervalForRequest = configuration.timeout; config.timeoutIntervalForResource = configuration.timeout
43
+ self.session = URLSession(configuration: config, delegate: NoRedirect(), delegateQueue: nil)
44
+ }
45
+ func send(path: String, method: String, authorization: String, body: Data?) async throws -> Data {
46
+ guard !path.contains(".."), !path.contains("?"), !path.contains("#"), !path.hasPrefix("/") else { throw IndianaClientError.invalidConfiguration }
47
+ var request = URLRequest(url: requestOrigin.appendingPathComponent("api/v1").appendingPathComponent(path))
48
+ request.httpMethod = method; request.httpBody = body
49
+ request.setValue("application/json", forHTTPHeaderField: "Content-Type")
50
+ if !authorization.isEmpty { request.setValue("Bearer \(authorization)", forHTTPHeaderField: "Authorization") }
51
+ request.setValue(configuration.scope.projectId.uuidString.lowercased(), forHTTPHeaderField: "X-Indiana-Project")
52
+ request.setValue(configuration.scope.environment.rawValue, forHTTPHeaderField: "X-Indiana-Environment")
53
+ request.setValue(IndianaProtocol.wireProtocol, forHTTPHeaderField: "X-Indiana-Protocol")
54
+ request.setValue(IndianaSDK.version, forHTTPHeaderField: "X-Indiana-SDK-Version")
55
+ do {
56
+ let (bytes, response) = try await session.bytes(for: request)
57
+ guard let http = response as? HTTPURLResponse, (200..<300).contains(http.statusCode) else {
58
+ throw IndianaClientError.requestFailed((response as? HTTPURLResponse)?.statusCode ?? 0)
59
+ }
60
+ try Self.requireCurrentProtocol(http.value(forHTTPHeaderField: "X-Indiana-Protocol"))
61
+ if response.expectedContentLength > 2_097_152 { throw IndianaClientError.invalidResponse }
62
+ var data = Data()
63
+ for try await byte in bytes {
64
+ guard data.count < 2_097_152 else { throw IndianaClientError.invalidResponse }
65
+ data.append(byte)
66
+ }
67
+ return data
68
+ } catch let error as IndianaClientError { throw error }
69
+ catch { throw IndianaClientError.temporaryUnavailable }
70
+ }
71
+ private final class NoRedirect: NSObject, URLSessionTaskDelegate, Sendable {
72
+ func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { completionHandler(nil) }
73
+ }
74
+ }