expo-iap 3.1.1-rc.1 โ 3.1.1-rc.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/coverage/clover.xml +2 -2
- package/coverage/lcov-report/index.html +1 -1
- package/coverage/lcov-report/src/helpers/index.html +1 -1
- package/coverage/lcov-report/src/helpers/subscription.ts.html +1 -1
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/index.ts.html +1 -1
- package/coverage/lcov-report/src/modules/android.ts.html +1 -1
- package/coverage/lcov-report/src/modules/index.html +1 -1
- package/coverage/lcov-report/src/modules/ios.ts.html +1 -1
- package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
- package/coverage/lcov-report/src/utils/index.html +1 -1
- package/expo-module.config.json +1 -1
- package/ios/{OneSideModule.swift โ onside/OnsideIapModule.swift} +23 -23
- package/package.json +2 -2
- package/plugin/build/withIAP.js +4 -4
- package/plugin/src/withIAP.ts +4 -4
- package/ios/expoiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/expoiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
package/coverage/clover.xml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<coverage generated="
|
|
3
|
-
<project timestamp="
|
|
2
|
+
<coverage generated="1758476468561" clover="3.2.0">
|
|
3
|
+
<project timestamp="1758476468561" name="All files">
|
|
4
4
|
<metrics statements="464" coveredstatements="459" conditionals="252" coveredconditionals="230" methods="84" coveredmethods="75" elements="800" coveredelements="764" complexity="0" loc="464" ncloc="464" packages="4" files="5" classes="5"/>
|
|
5
5
|
<package name="src">
|
|
6
6
|
<metrics statements="188" coveredstatements="187" conditionals="88" coveredconditionals="80" methods="38" coveredmethods="30"/>
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
147
147
|
Code coverage generated by
|
|
148
148
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
149
|
-
at 2025-09-
|
|
149
|
+
at 2025-09-21T17:41:08.551Z
|
|
150
150
|
</div>
|
|
151
151
|
<script src="prettify.js"></script>
|
|
152
152
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2025-09-
|
|
104
|
+
at 2025-09-21T17:41:08.551Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -481,7 +481,7 @@ export const hasActiveSubscriptions = async (
|
|
|
481
481
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
482
482
|
Code coverage generated by
|
|
483
483
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
484
|
-
at 2025-09-
|
|
484
|
+
at 2025-09-21T17:41:08.551Z
|
|
485
485
|
</div>
|
|
486
486
|
<script src="../../prettify.js"></script>
|
|
487
487
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2025-09-
|
|
104
|
+
at 2025-09-21T17:41:08.551Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -1978,7 +1978,7 @@ export type {
|
|
|
1978
1978
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1979
1979
|
Code coverage generated by
|
|
1980
1980
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1981
|
-
at 2025-09-
|
|
1981
|
+
at 2025-09-21T17:41:08.551Z
|
|
1982
1982
|
</div>
|
|
1983
1983
|
<script src="../prettify.js"></script>
|
|
1984
1984
|
<script>
|
|
@@ -535,7 +535,7 @@ export const openRedeemOfferCodeAndroid = async (): Promise<void> => {
|
|
|
535
535
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
536
536
|
Code coverage generated by
|
|
537
537
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
538
|
-
at 2025-09-
|
|
538
|
+
at 2025-09-21T17:41:08.551Z
|
|
539
539
|
</div>
|
|
540
540
|
<script src="../../prettify.js"></script>
|
|
541
541
|
<script>
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
117
117
|
Code coverage generated by
|
|
118
118
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
119
|
-
at 2025-09-
|
|
119
|
+
at 2025-09-21T17:41:08.551Z
|
|
120
120
|
</div>
|
|
121
121
|
<script src="../../prettify.js"></script>
|
|
122
122
|
<script>
|
|
@@ -1207,7 +1207,7 @@ export const deepLinkToSubscriptionsIOS = (): Promise<void> =>
|
|
|
1207
1207
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1208
1208
|
Code coverage generated by
|
|
1209
1209
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1210
|
-
at 2025-09-
|
|
1210
|
+
at 2025-09-21T17:41:08.551Z
|
|
1211
1211
|
</div>
|
|
1212
1212
|
<script src="../../prettify.js"></script>
|
|
1213
1213
|
<script>
|
|
@@ -1054,7 +1054,7 @@ export function getUserFriendlyErrorMessage(error: ErrorLike): string {
|
|
|
1054
1054
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1055
1055
|
Code coverage generated by
|
|
1056
1056
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1057
|
-
at 2025-09-
|
|
1057
|
+
at 2025-09-21T17:41:08.551Z
|
|
1058
1058
|
</div>
|
|
1059
1059
|
<script src="../../prettify.js"></script>
|
|
1060
1060
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2025-09-
|
|
104
|
+
at 2025-09-21T17:41:08.551Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../../prettify.js"></script>
|
|
107
107
|
<script>
|
package/expo-module.config.json
CHANGED
|
@@ -8,7 +8,7 @@ private enum OnsideEvent: String {
|
|
|
8
8
|
case promotedProductIOS = "promoted-product-ios"
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
private enum
|
|
11
|
+
private enum OnsideBridgeError: Error, LocalizedError {
|
|
12
12
|
case sdkUnavailable
|
|
13
13
|
case notInitialized
|
|
14
14
|
case emptySkuList
|
|
@@ -42,7 +42,7 @@ import OnsideKit
|
|
|
42
42
|
|
|
43
43
|
@available(iOS 16.0, *)
|
|
44
44
|
@MainActor
|
|
45
|
-
public final class
|
|
45
|
+
public final class OnsideIapModule: Module {
|
|
46
46
|
private var isInitialized = false
|
|
47
47
|
private var restoreContinuation: CheckedContinuation<Bool, Error>?
|
|
48
48
|
private let transactionObserver = OnsideTransactionObserverBridge()
|
|
@@ -99,13 +99,13 @@ public final class OneSideModule: Module {
|
|
|
99
99
|
|
|
100
100
|
let request = try ExpoIapHelper.decodeProductRequest(from: params)
|
|
101
101
|
guard !request.skus.isEmpty else {
|
|
102
|
-
throw
|
|
102
|
+
throw OnsideBridgeError.emptySkuList
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
let response = try await productFetcher.fetch(identifiers: Set(request.skus))
|
|
106
106
|
|
|
107
107
|
if !response.invalidProductIdentifiers.isEmpty {
|
|
108
|
-
throw
|
|
108
|
+
throw OnsideBridgeError.productNotFound(response.invalidProductIdentifiers.joined(separator: ", "))
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
response.products.forEach { productCache[$0.productIdentifier] = $0 }
|
|
@@ -120,12 +120,12 @@ public final class OneSideModule: Module {
|
|
|
120
120
|
try await ensureObserverRegistered()
|
|
121
121
|
|
|
122
122
|
guard let sku = resolveSku(from: payload) else {
|
|
123
|
-
throw
|
|
123
|
+
throw OnsideBridgeError.emptySkuList
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
try await ensureProductAvailable(sku: sku)
|
|
127
127
|
guard let product = productCache[sku] else {
|
|
128
|
-
throw
|
|
128
|
+
throw OnsideBridgeError.productNotFound(sku)
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
|
|
@@ -134,7 +134,7 @@ public final class OneSideModule: Module {
|
|
|
134
134
|
case .success:
|
|
135
135
|
continuation.resume()
|
|
136
136
|
case .failure(let error):
|
|
137
|
-
continuation.resume(throwing:
|
|
137
|
+
continuation.resume(throwing: OnsideBridgeError.queueError(error.localizedDescription))
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
}
|
|
@@ -151,7 +151,7 @@ public final class OneSideModule: Module {
|
|
|
151
151
|
guard let transactionId = purchasePayload["transactionId"] as? String,
|
|
152
152
|
let uuid = UUID(uuidString: transactionId),
|
|
153
153
|
let transaction = transactionCache[uuid] else {
|
|
154
|
-
throw
|
|
154
|
+
throw OnsideBridgeError.transactionNotFound(purchasePayload["transactionId"] as? String ?? "")
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
Onside.paymentQueue().finishTransaction(transaction)
|
|
@@ -165,7 +165,7 @@ public final class OneSideModule: Module {
|
|
|
165
165
|
try await ensureObserverRegistered()
|
|
166
166
|
|
|
167
167
|
if restoreContinuation != nil {
|
|
168
|
-
throw
|
|
168
|
+
throw OnsideBridgeError.restoreInProgress
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
return try await withCheckedThrowingContinuation { continuation in
|
|
@@ -179,7 +179,7 @@ public final class OneSideModule: Module {
|
|
|
179
179
|
case .success:
|
|
180
180
|
continuation.resume(returning: true)
|
|
181
181
|
case .failure(let error):
|
|
182
|
-
continuation.resume(throwing:
|
|
182
|
+
continuation.resume(throwing: OnsideBridgeError.queueError(error.localizedDescription))
|
|
183
183
|
}
|
|
184
184
|
restoreContinuation = nil
|
|
185
185
|
}
|
|
@@ -208,7 +208,7 @@ public final class OneSideModule: Module {
|
|
|
208
208
|
}
|
|
209
209
|
let response = try await productFetcher.fetch(identifiers: [sku])
|
|
210
210
|
if !response.invalidProductIdentifiers.isEmpty {
|
|
211
|
-
throw
|
|
211
|
+
throw OnsideBridgeError.productNotFound(sku)
|
|
212
212
|
}
|
|
213
213
|
response.products.forEach { productCache[$0.productIdentifier] = $0 }
|
|
214
214
|
}
|
|
@@ -230,7 +230,7 @@ public final class OneSideModule: Module {
|
|
|
230
230
|
|
|
231
231
|
transactionObserver.onRestoreFailed = { [weak self] error in
|
|
232
232
|
guard let self else { return }
|
|
233
|
-
restoreContinuation?.resume(throwing:
|
|
233
|
+
restoreContinuation?.resume(throwing: OnsideBridgeError.queueError(error.localizedDescription))
|
|
234
234
|
restoreContinuation = nil
|
|
235
235
|
}
|
|
236
236
|
}
|
|
@@ -312,7 +312,7 @@ public final class OneSideModule: Module {
|
|
|
312
312
|
private func encodeToJSONString<T: Encodable>(_ value: T) throws -> String {
|
|
313
313
|
let data = try encoder.encode(value)
|
|
314
314
|
guard let json = String(data: data, encoding: .utf8) else {
|
|
315
|
-
throw
|
|
315
|
+
throw OnsideBridgeError.queueError("Unable to encode JSON string")
|
|
316
316
|
}
|
|
317
317
|
return json
|
|
318
318
|
}
|
|
@@ -408,7 +408,7 @@ private final class OnsideProductFetcher: NSObject, OnsideProductsRequestDelegat
|
|
|
408
408
|
|
|
409
409
|
func fetch(identifiers: Set<String>) async throws -> OnsideProductsResponse {
|
|
410
410
|
guard !identifiers.isEmpty else {
|
|
411
|
-
throw
|
|
411
|
+
throw OnsideBridgeError.emptySkuList
|
|
412
412
|
}
|
|
413
413
|
|
|
414
414
|
return try await withCheckedThrowingContinuation { continuation in
|
|
@@ -426,7 +426,7 @@ private final class OnsideProductFetcher: NSObject, OnsideProductsRequestDelegat
|
|
|
426
426
|
}
|
|
427
427
|
|
|
428
428
|
func onsideProductsRequestRequest(_ request: OnsideProductsRequest, didFailWithError error: OnsideProductsRequestError) {
|
|
429
|
-
continuation?.resume(throwing:
|
|
429
|
+
continuation?.resume(throwing: OnsideBridgeError.queueError(error.localizedDescription))
|
|
430
430
|
cleanup()
|
|
431
431
|
}
|
|
432
432
|
|
|
@@ -446,7 +446,7 @@ private final class OnsideProductFetcher: NSObject, OnsideProductsRequestDelegat
|
|
|
446
446
|
|
|
447
447
|
@available(iOS 15.0, tvOS 15.0, *)
|
|
448
448
|
@MainActor
|
|
449
|
-
public final class
|
|
449
|
+
public final class OnsideIapModule: Module {
|
|
450
450
|
nonisolated public func definition() -> ModuleDefinition {
|
|
451
451
|
Name("ExpoIapOnside")
|
|
452
452
|
|
|
@@ -457,31 +457,31 @@ public final class OneSideModule: Module {
|
|
|
457
457
|
)
|
|
458
458
|
|
|
459
459
|
AsyncFunction("initConnection") { () async throws -> Bool in
|
|
460
|
-
throw
|
|
460
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
461
461
|
}
|
|
462
462
|
|
|
463
463
|
AsyncFunction("endConnection") { () async throws -> Bool in
|
|
464
|
-
throw
|
|
464
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
AsyncFunction("fetchProducts") { (_: [String: Any]) async throws -> [[String: Any]] in
|
|
468
|
-
throw
|
|
468
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
469
469
|
}
|
|
470
470
|
|
|
471
471
|
AsyncFunction("requestPurchase") { (_: [String: Any]) async throws -> Any? in
|
|
472
|
-
throw
|
|
472
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
473
473
|
}
|
|
474
474
|
|
|
475
475
|
AsyncFunction("finishTransaction") { (_: [String: Any], _: Bool?) async throws -> Bool in
|
|
476
|
-
throw
|
|
476
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
477
477
|
}
|
|
478
478
|
|
|
479
479
|
AsyncFunction("restorePurchases") { () async throws -> Bool in
|
|
480
|
-
throw
|
|
480
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
AsyncFunction("getStorefrontIOS") { () async throws -> String in
|
|
484
|
-
throw
|
|
484
|
+
throw OnsideBridgeError.sdkUnavailable
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-iap",
|
|
3
|
-
"version": "3.1.1-rc.
|
|
3
|
+
"version": "3.1.1-rc.2",
|
|
4
4
|
"description": "In App Purchase module in Expo",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"test": "jest && bun run test:plugin",
|
|
17
17
|
"test:plugin": "cd plugin && npx jest",
|
|
18
18
|
"test:coverage": "jest --coverage",
|
|
19
|
-
"prepare": "expo-module prepare && sh -c 'command -v husky >/dev/null 2>&1 && husky install || { echo \"husky not installed; skipping\"; exit 0; }'",
|
|
19
|
+
"prepare": "bun clean:plugin && bun clean && expo-module prepare && sh -c 'command -v husky >/dev/null 2>&1 && husky install || { echo \"husky not installed; skipping\"; exit 0; }'",
|
|
20
20
|
"expo-module": "expo-module",
|
|
21
21
|
"open:ios": "xed example/ios",
|
|
22
22
|
"open:android": "open -a \"Android Studio\" example/android",
|
package/plugin/build/withIAP.js
CHANGED
|
@@ -165,7 +165,7 @@ const syncAutolinking = (state) => {
|
|
|
165
165
|
const config = JSON.parse(raw);
|
|
166
166
|
const iosConfig = config.ios ?? (config.ios = {});
|
|
167
167
|
const existing = Array.isArray(iosConfig.modules)
|
|
168
|
-
?
|
|
168
|
+
? iosConfig.modules.filter((module) => module !== 'OneSideModule')
|
|
169
169
|
: [];
|
|
170
170
|
const desiredEntries = [
|
|
171
171
|
{
|
|
@@ -175,10 +175,10 @@ const syncAutolinking = (state) => {
|
|
|
175
175
|
removeLog: '๐งน expo-iap: Disabled ExpoIapModule autolinking',
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
|
-
name: '
|
|
178
|
+
name: 'OnsideIapModule',
|
|
179
179
|
enable: state.onside,
|
|
180
|
-
addLog: '๐ expo-iap: Enabled
|
|
181
|
-
removeLog: '๐งน expo-iap: Disabled
|
|
180
|
+
addLog: '๐ expo-iap: Enabled OnsideIapModule autolinking',
|
|
181
|
+
removeLog: '๐งน expo-iap: Disabled OnsideIapModule autolinking',
|
|
182
182
|
},
|
|
183
183
|
];
|
|
184
184
|
const { modules: nextModules, added, removed, } = computeAutolinkModules(existing, desiredEntries.map(({ name, enable }) => ({ name, enable })));
|
package/plugin/src/withIAP.ts
CHANGED
|
@@ -211,7 +211,7 @@ const syncAutolinking = (state: AutolinkState) => {
|
|
|
211
211
|
const config = JSON.parse(raw);
|
|
212
212
|
const iosConfig = config.ios ?? (config.ios = {});
|
|
213
213
|
const existing: string[] = Array.isArray(iosConfig.modules)
|
|
214
|
-
?
|
|
214
|
+
? iosConfig.modules.filter((module: string) => module !== 'OneSideModule')
|
|
215
215
|
: [];
|
|
216
216
|
|
|
217
217
|
const desiredEntries: {
|
|
@@ -227,10 +227,10 @@ const syncAutolinking = (state: AutolinkState) => {
|
|
|
227
227
|
removeLog: '๐งน expo-iap: Disabled ExpoIapModule autolinking',
|
|
228
228
|
},
|
|
229
229
|
{
|
|
230
|
-
name: '
|
|
230
|
+
name: 'OnsideIapModule',
|
|
231
231
|
enable: state.onside,
|
|
232
|
-
addLog: '๐ expo-iap: Enabled
|
|
233
|
-
removeLog: '๐งน expo-iap: Disabled
|
|
232
|
+
addLog: '๐ expo-iap: Enabled OnsideIapModule autolinking',
|
|
233
|
+
removeLog: '๐งน expo-iap: Disabled OnsideIapModule autolinking',
|
|
234
234
|
},
|
|
235
235
|
];
|
|
236
236
|
|