@virex-tech/paywallo-sdk 1.5.0 → 1.5.2
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/PaywalloSdk.podspec +2 -3
- package/README.md +58 -37
- package/android/build.gradle +4 -1
- package/android/consumer-rules.pro +24 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloDeviceModule.kt +148 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloFBBridgeModule.kt +10 -7
- package/android/src/main/java/com/paywallo/sdk/PaywalloSdkPackage.kt +3 -1
- package/android/src/main/java/com/paywallo/sdk/PaywalloStorageModule.kt +106 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloStoreKitModule.kt +13 -2
- package/android/src/main/java/com/paywallo/sdk/PaywalloWebView.kt +39 -3
- package/android/src/main/java/com/paywallo/sdk/PaywalloWebViewEvent.kt +20 -0
- package/dist/index.d.mts +18 -14
- package/dist/index.d.ts +18 -14
- package/dist/index.js +727 -469
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +693 -435
- package/dist/index.mjs.map +1 -1
- package/ios/PaywalloDevice.m +8 -0
- package/ios/PaywalloDevice.swift +91 -0
- package/ios/PaywalloFBBridge.swift +51 -0
- package/ios/PaywalloStorage.m +35 -0
- package/ios/PaywalloStorage.swift +171 -0
- package/ios/PaywalloStoreKit.swift +16 -2
- package/ios/PaywalloWebView.m +20 -0
- package/package.json +12 -11
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
import CoreTelephony
|
|
4
|
+
|
|
5
|
+
@objc(PaywalloDevice)
|
|
6
|
+
class PaywalloDevice: NSObject {
|
|
7
|
+
|
|
8
|
+
// requiresMainQueueSetup = true so UIDevice properties are read on the main thread
|
|
9
|
+
@objc static func requiresMainQueueSetup() -> Bool { return true }
|
|
10
|
+
|
|
11
|
+
// MARK: - Get Device Info
|
|
12
|
+
|
|
13
|
+
@objc
|
|
14
|
+
func getDeviceInfo(
|
|
15
|
+
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
16
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
17
|
+
) {
|
|
18
|
+
// UIDevice properties are MainActor — must be read on the main thread
|
|
19
|
+
DispatchQueue.main.async {
|
|
20
|
+
let device = UIDevice.current
|
|
21
|
+
let processInfo = ProcessInfo.processInfo
|
|
22
|
+
let bundle = Bundle.main
|
|
23
|
+
let info = bundle.infoDictionary
|
|
24
|
+
|
|
25
|
+
let deviceId = device.identifierForVendor?.uuidString ?? ""
|
|
26
|
+
let model = device.model
|
|
27
|
+
let systemVersion = device.systemVersion
|
|
28
|
+
let systemName = device.systemName
|
|
29
|
+
let appVersion = info?["CFBundleShortVersionString"] as? String ?? "unknown"
|
|
30
|
+
let buildNumber = info?["CFBundleVersion"] as? String ?? "unknown"
|
|
31
|
+
let bundleId = bundle.bundleIdentifier ?? "unknown"
|
|
32
|
+
let totalRam = NSNumber(value: processInfo.physicalMemory)
|
|
33
|
+
|
|
34
|
+
// Disk stats — off main thread safe but called here for simplicity
|
|
35
|
+
var totalDisk: NSNumber = 0
|
|
36
|
+
var freeDisk: NSNumber = 0
|
|
37
|
+
do {
|
|
38
|
+
let attrs = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())
|
|
39
|
+
if let size = attrs[.systemSize] as? NSNumber { totalDisk = size }
|
|
40
|
+
if let free = attrs[.systemFreeSize] as? NSNumber { freeDisk = free }
|
|
41
|
+
} catch {
|
|
42
|
+
// fallback stays 0
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Model identifier (sysctl — safe on any thread)
|
|
46
|
+
let modelId = self.getModelIdentifier()
|
|
47
|
+
|
|
48
|
+
// Carrier: CTTelephonyNetworkInfo is deprecated in iOS 16+ but still functional.
|
|
49
|
+
// Using conditional to suppress warning; no replacement API exists for carrier name.
|
|
50
|
+
var carrier = "unknown"
|
|
51
|
+
let networkInfo = CTTelephonyNetworkInfo()
|
|
52
|
+
if let providers = networkInfo.serviceSubscriberCellularProviders,
|
|
53
|
+
let first = providers.values.first,
|
|
54
|
+
let name = first.carrierName
|
|
55
|
+
{
|
|
56
|
+
carrier = name
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let result: NSDictionary = [
|
|
60
|
+
"deviceId": deviceId,
|
|
61
|
+
"model": model,
|
|
62
|
+
"modelId": modelId,
|
|
63
|
+
"systemVersion": systemVersion,
|
|
64
|
+
"appVersion": appVersion,
|
|
65
|
+
"buildNumber": buildNumber,
|
|
66
|
+
"bundleId": bundleId,
|
|
67
|
+
"brand": "Apple",
|
|
68
|
+
"systemName": systemName,
|
|
69
|
+
"totalDisk": totalDisk,
|
|
70
|
+
"freeDisk": freeDisk,
|
|
71
|
+
"totalRam": totalRam,
|
|
72
|
+
"carrier": carrier,
|
|
73
|
+
"idfv": deviceId,
|
|
74
|
+
"installerPackage": NSNull(),
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
resolve(result)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// MARK: - Helpers
|
|
82
|
+
|
|
83
|
+
private func getModelIdentifier() -> String {
|
|
84
|
+
var size = 0
|
|
85
|
+
sysctlbyname("hw.machine", nil, &size, nil, 0)
|
|
86
|
+
guard size > 0 else { return "unknown" }
|
|
87
|
+
var machine = [CChar](repeating: 0, count: size)
|
|
88
|
+
sysctlbyname("hw.machine", &machine, &size, nil, 0)
|
|
89
|
+
return String(cString: machine)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Foundation
|
|
2
|
+
|
|
3
|
+
#if canImport(FBSDKCoreKit)
|
|
2
4
|
import FBSDKCoreKit
|
|
3
5
|
|
|
4
6
|
@objc(PaywalloFBBridge)
|
|
@@ -75,3 +77,52 @@ class PaywalloFBBridge: NSObject {
|
|
|
75
77
|
return false
|
|
76
78
|
}
|
|
77
79
|
}
|
|
80
|
+
|
|
81
|
+
#else
|
|
82
|
+
|
|
83
|
+
// Stub: FBSDKCoreKit not available — all methods are no-ops
|
|
84
|
+
@objc(PaywalloFBBridge)
|
|
85
|
+
class PaywalloFBBridge: NSObject {
|
|
86
|
+
|
|
87
|
+
@objc
|
|
88
|
+
func getAnonymousID(
|
|
89
|
+
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
90
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
91
|
+
) {
|
|
92
|
+
resolve(nil)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@objc
|
|
96
|
+
func logEvent(
|
|
97
|
+
_ name: String,
|
|
98
|
+
params: NSDictionary,
|
|
99
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
100
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
101
|
+
) {
|
|
102
|
+
resolve(nil)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@objc
|
|
106
|
+
func logPurchase(
|
|
107
|
+
_ amount: Double,
|
|
108
|
+
currency: String,
|
|
109
|
+
params: NSDictionary,
|
|
110
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
111
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
112
|
+
) {
|
|
113
|
+
resolve(nil)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@objc
|
|
117
|
+
func setUserID(_ userId: String) {}
|
|
118
|
+
|
|
119
|
+
@objc
|
|
120
|
+
func flush() {}
|
|
121
|
+
|
|
122
|
+
@objc
|
|
123
|
+
static func requiresMainQueueSetup() -> Bool {
|
|
124
|
+
return false
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#endif
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
@interface RCT_EXTERN_MODULE(PaywalloStorage, NSObject)
|
|
4
|
+
|
|
5
|
+
RCT_EXTERN_METHOD(secureGet:(NSString *)key
|
|
6
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
7
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
8
|
+
|
|
9
|
+
RCT_EXTERN_METHOD(secureSet:(NSString *)key
|
|
10
|
+
value:(NSString *)value
|
|
11
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
12
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
13
|
+
|
|
14
|
+
RCT_EXTERN_METHOD(secureRemove:(NSString *)key
|
|
15
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
16
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
17
|
+
|
|
18
|
+
RCT_EXTERN_METHOD(legacySecureGet:(NSString *)legacyService
|
|
19
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
20
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
21
|
+
|
|
22
|
+
RCT_EXTERN_METHOD(get:(NSString *)key
|
|
23
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
24
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
25
|
+
|
|
26
|
+
RCT_EXTERN_METHOD(set:(NSString *)key
|
|
27
|
+
value:(NSString *)value
|
|
28
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
29
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
30
|
+
|
|
31
|
+
RCT_EXTERN_METHOD(remove:(NSString *)key
|
|
32
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
33
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
34
|
+
|
|
35
|
+
@end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Security
|
|
3
|
+
|
|
4
|
+
@objc(PaywalloStorage)
|
|
5
|
+
class PaywalloStorage: NSObject {
|
|
6
|
+
|
|
7
|
+
private let service = "com.paywallo.sdk"
|
|
8
|
+
// Serial queue keeps Keychain ops off the main thread and serialized
|
|
9
|
+
private let keychainQueue = DispatchQueue(label: "com.paywallo.sdk.keychain", qos: .userInitiated)
|
|
10
|
+
|
|
11
|
+
// MARK: - Secure Storage (Keychain)
|
|
12
|
+
|
|
13
|
+
@objc
|
|
14
|
+
func secureGet(
|
|
15
|
+
_ key: String,
|
|
16
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
17
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
18
|
+
) {
|
|
19
|
+
keychainQueue.async {
|
|
20
|
+
// kSecAttrAccessible must NOT be included in CopyMatching queries —
|
|
21
|
+
// it is an attribute filter and causes errSecItemNotFound when the
|
|
22
|
+
// stored item's accessibility differs from the queried value.
|
|
23
|
+
let query: [String: Any] = [
|
|
24
|
+
kSecClass as String: kSecClassGenericPassword,
|
|
25
|
+
kSecAttrService as String: self.service,
|
|
26
|
+
kSecAttrAccount as String: key,
|
|
27
|
+
kSecReturnData as String: true,
|
|
28
|
+
kSecMatchLimit as String: kSecMatchLimitOne,
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
var item: CFTypeRef?
|
|
32
|
+
let status = SecItemCopyMatching(query as CFDictionary, &item)
|
|
33
|
+
|
|
34
|
+
if status == errSecSuccess,
|
|
35
|
+
let data = item as? Data,
|
|
36
|
+
let value = String(data: data, encoding: .utf8)
|
|
37
|
+
{
|
|
38
|
+
resolve(value)
|
|
39
|
+
} else {
|
|
40
|
+
resolve(nil)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@objc
|
|
46
|
+
func secureSet(
|
|
47
|
+
_ key: String,
|
|
48
|
+
value: String,
|
|
49
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
50
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
51
|
+
) {
|
|
52
|
+
guard let data = value.data(using: .utf8) else {
|
|
53
|
+
resolve(false)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
keychainQueue.async {
|
|
58
|
+
let query: [String: Any] = [
|
|
59
|
+
kSecClass as String: kSecClassGenericPassword,
|
|
60
|
+
kSecAttrService as String: self.service,
|
|
61
|
+
kSecAttrAccount as String: key,
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
let attributes: [String: Any] = [
|
|
65
|
+
kSecValueData as String: data,
|
|
66
|
+
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
let updateStatus = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
|
|
70
|
+
|
|
71
|
+
if updateStatus == errSecItemNotFound {
|
|
72
|
+
var addQuery = query
|
|
73
|
+
addQuery[kSecValueData as String] = data
|
|
74
|
+
addQuery[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
|
|
75
|
+
let addStatus = SecItemAdd(addQuery as CFDictionary, nil)
|
|
76
|
+
resolve(addStatus == errSecSuccess)
|
|
77
|
+
} else {
|
|
78
|
+
resolve(updateStatus == errSecSuccess)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@objc
|
|
84
|
+
func secureRemove(
|
|
85
|
+
_ key: String,
|
|
86
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
87
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
88
|
+
) {
|
|
89
|
+
keychainQueue.async {
|
|
90
|
+
let query: [String: Any] = [
|
|
91
|
+
kSecClass as String: kSecClassGenericPassword,
|
|
92
|
+
kSecAttrService as String: self.service,
|
|
93
|
+
kSecAttrAccount as String: key,
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
SecItemDelete(query as CFDictionary)
|
|
97
|
+
resolve(true)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// MARK: - Legacy Migration (SDK ≤1.5.0 → ≥1.5.2)
|
|
102
|
+
// react-native-keychain stored: service="com.paywallo.sdk.{key}", account="panel"
|
|
103
|
+
// This read-only helper is called once during migration and never written to.
|
|
104
|
+
|
|
105
|
+
@objc
|
|
106
|
+
func legacySecureGet(
|
|
107
|
+
_ legacyService: String,
|
|
108
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
109
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
110
|
+
) {
|
|
111
|
+
keychainQueue.async {
|
|
112
|
+
let query: [String: Any] = [
|
|
113
|
+
kSecClass as String: kSecClassGenericPassword,
|
|
114
|
+
kSecAttrService as String: legacyService,
|
|
115
|
+
kSecAttrAccount as String: "panel",
|
|
116
|
+
kSecReturnData as String: true,
|
|
117
|
+
kSecMatchLimit as String: kSecMatchLimitOne,
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
var item: CFTypeRef?
|
|
121
|
+
let status = SecItemCopyMatching(query as CFDictionary, &item)
|
|
122
|
+
|
|
123
|
+
if status == errSecSuccess,
|
|
124
|
+
let data = item as? Data,
|
|
125
|
+
let value = String(data: data, encoding: .utf8)
|
|
126
|
+
{
|
|
127
|
+
resolve(value)
|
|
128
|
+
} else {
|
|
129
|
+
resolve(nil)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// MARK: - Regular Storage (UserDefaults)
|
|
135
|
+
|
|
136
|
+
@objc
|
|
137
|
+
func get(
|
|
138
|
+
_ key: String,
|
|
139
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
140
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
141
|
+
) {
|
|
142
|
+
let value = UserDefaults.standard.string(forKey: key)
|
|
143
|
+
resolve(value)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@objc
|
|
147
|
+
func set(
|
|
148
|
+
_ key: String,
|
|
149
|
+
value: String,
|
|
150
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
151
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
152
|
+
) {
|
|
153
|
+
UserDefaults.standard.set(value, forKey: key)
|
|
154
|
+
resolve(true)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@objc
|
|
158
|
+
func remove(
|
|
159
|
+
_ key: String,
|
|
160
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
161
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
162
|
+
) {
|
|
163
|
+
UserDefaults.standard.removeObject(forKey: key)
|
|
164
|
+
resolve(true)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@objc
|
|
168
|
+
static func requiresMainQueueSetup() -> Bool {
|
|
169
|
+
return false
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -23,7 +23,9 @@ class PaywalloStoreKit: NSObject {
|
|
|
23
23
|
for await result in Transaction.updates {
|
|
24
24
|
guard let _ = self else { return }
|
|
25
25
|
if case .verified(let transaction) = result {
|
|
26
|
+
#if DEBUG
|
|
26
27
|
print("[Paywallo:StoreKit] Transaction update: \(transaction.productID) status=\(transaction.revocationDate != nil ? "revoked" : "active") id=\(transaction.id)")
|
|
28
|
+
#endif
|
|
27
29
|
await transaction.finish()
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -38,7 +40,11 @@ class PaywalloStoreKit: NSObject {
|
|
|
38
40
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
39
41
|
reject: @escaping RCTPromiseRejectBlock
|
|
40
42
|
) {
|
|
41
|
-
Task {
|
|
43
|
+
Task { [weak self] in
|
|
44
|
+
guard let self else {
|
|
45
|
+
reject("MODULE_DEALLOCATED", "Module was deallocated", nil)
|
|
46
|
+
return
|
|
47
|
+
}
|
|
42
48
|
do {
|
|
43
49
|
let products = try await Product.products(for: Set(productIds))
|
|
44
50
|
let result = products.map { self.productToDict($0) }
|
|
@@ -58,18 +64,26 @@ class PaywalloStoreKit: NSObject {
|
|
|
58
64
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
59
65
|
reject: @escaping RCTPromiseRejectBlock
|
|
60
66
|
) {
|
|
61
|
-
Task {
|
|
67
|
+
Task { [weak self] in
|
|
68
|
+
guard self != nil else {
|
|
69
|
+
reject("MODULE_DEALLOCATED", "Module was deallocated", nil)
|
|
70
|
+
return
|
|
71
|
+
}
|
|
62
72
|
do {
|
|
63
73
|
var clearedCount = 0
|
|
64
74
|
for await result in Transaction.unfinished {
|
|
65
75
|
if case .verified(let tx) = result {
|
|
76
|
+
#if DEBUG
|
|
66
77
|
print("[Paywallo:StoreKit] Clearing unfinished tx: \(tx.productID) id=\(tx.id)")
|
|
78
|
+
#endif
|
|
67
79
|
await tx.finish()
|
|
68
80
|
clearedCount += 1
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
if clearedCount > 0 {
|
|
84
|
+
#if DEBUG
|
|
72
85
|
print("[Paywallo:StoreKit] Cleared \(clearedCount) unfinished transaction(s)")
|
|
86
|
+
#endif
|
|
73
87
|
}
|
|
74
88
|
|
|
75
89
|
let products = try await Product.products(for: [productId])
|
package/ios/PaywalloWebView.m
CHANGED
|
@@ -190,6 +190,26 @@
|
|
|
190
190
|
return;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
// Allow HTTPS, about: (initial blank), and schemes that must be handed off to the OS
|
|
194
|
+
// (mailto, App Store). Block everything else — including plain HTTP, javascript:,
|
|
195
|
+
// data:, and blob: — to prevent mixed-content and injection attacks.
|
|
196
|
+
NSString *scheme = url.scheme.lowercaseString;
|
|
197
|
+
NSSet<NSString *> *allowedSchemes = [NSSet setWithObjects:
|
|
198
|
+
@"https", @"about", @"mailto", @"itms-apps", @"itms-services", nil];
|
|
199
|
+
if (scheme && ![allowedSchemes containsObject:scheme]) {
|
|
200
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// mailto: and App Store links must be opened by the OS, not loaded inside the WebView.
|
|
205
|
+
if ([scheme isEqualToString:@"mailto"] ||
|
|
206
|
+
[scheme isEqualToString:@"itms-apps"] ||
|
|
207
|
+
[scheme isEqualToString:@"itms-services"]) {
|
|
208
|
+
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
|
209
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
193
213
|
decisionHandler(WKNavigationActionPolicyAllow);
|
|
194
214
|
}
|
|
195
215
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@virex-tech/paywallo-sdk",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "SDK React Native para integração com Paywallo - Paywalls, Subscriptions e Analytics",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"ios",
|
|
19
19
|
"android",
|
|
20
20
|
"PaywalloSdk.podspec",
|
|
21
|
-
"react-native.config.js"
|
|
21
|
+
"react-native.config.js",
|
|
22
|
+
"LICENSE"
|
|
22
23
|
],
|
|
23
24
|
"react-native": "./dist/index.mjs",
|
|
24
25
|
"scripts": {
|
|
@@ -60,20 +61,20 @@
|
|
|
60
61
|
"engines": {
|
|
61
62
|
"node": ">=18.0.0"
|
|
62
63
|
},
|
|
63
|
-
"dependencies": {
|
|
64
|
-
"@react-native-async-storage/async-storage": ">=1.0.0",
|
|
65
|
-
"expo-application": ">=5.0.0",
|
|
66
|
-
"expo-tracking-transparency": ">=0.5.0",
|
|
67
|
-
"react-native-device-info": ">=10.0.0",
|
|
68
|
-
"react-native-keychain": "^10.0.0"
|
|
69
|
-
},
|
|
70
64
|
"peerDependencies": {
|
|
71
|
-
"
|
|
72
|
-
"react
|
|
65
|
+
"expo-tracking-transparency": "*",
|
|
66
|
+
"react": "*",
|
|
67
|
+
"react-native": "*"
|
|
68
|
+
},
|
|
69
|
+
"peerDependenciesMeta": {
|
|
70
|
+
"expo-tracking-transparency": {
|
|
71
|
+
"optional": true
|
|
72
|
+
}
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@eslint/js": "^9.0.0",
|
|
76
76
|
"@types/react": "^19.0.0",
|
|
77
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
77
78
|
"eslint": "^9.0.0",
|
|
78
79
|
"eslint-config-prettier": "^10.0.0",
|
|
79
80
|
"eslint-plugin-simple-import-sort": "^12.0.0",
|