@tinkerlandai/indiana-react-native 0.9.1 → 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,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
|
+
}
|