expo-iap 5.3.1 → 5.3.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/{CLAUDE.md → AGENTS.md} +1 -3
- package/CONTRIBUTING.md +5 -12
- package/README.md +2 -2
- package/android/src/main/java/expo/modules/iap/ExpoIapLog.kt +4 -0
- package/bun.lock +421 -1139
- package/ios/ExpoIapLog.swift +6 -6
- package/ios/onside/OnsideIapModule.swift +1 -1
- package/openiap-versions.json +1 -1
- package/osv-scanner.toml +9 -0
- package/package.json +8 -2
- package/plugin/build/withVega.js +10 -0
- package/plugin/src/withVega.ts +10 -0
- package/tests/ios/ExpoIapLogTests.swift +37 -0
package/ios/ExpoIapLog.swift
CHANGED
|
@@ -109,7 +109,7 @@ enum ExpoIapLog {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
private static func sanitize(_ value: Any?) -> Any? {
|
|
112
|
-
guard let value else { return nil }
|
|
112
|
+
guard let value, !(value is NSNull) else { return nil }
|
|
113
113
|
|
|
114
114
|
if let string = value as? String {
|
|
115
115
|
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
@@ -121,20 +121,20 @@ enum ExpoIapLog {
|
|
|
121
121
|
return sanitize(json) ?? string
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
if let dictionary = value as? [String: Any] {
|
|
125
|
-
return sanitizeDictionary(dictionary)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
124
|
if let optionalDictionary = value as? [String: Any?] {
|
|
129
125
|
var compact: [String: Any] = [:]
|
|
130
126
|
for (key, optionalValue) in optionalDictionary {
|
|
131
|
-
if let optionalValue {
|
|
127
|
+
if let optionalValue, !(optionalValue is NSNull) {
|
|
132
128
|
compact[key] = optionalValue
|
|
133
129
|
}
|
|
134
130
|
}
|
|
135
131
|
return sanitizeDictionary(compact)
|
|
136
132
|
}
|
|
137
133
|
|
|
134
|
+
if let dictionary = value as? [String: Any] {
|
|
135
|
+
return sanitizeDictionary(dictionary)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
138
|
if let array = value as? [Any] {
|
|
139
139
|
return array.compactMap { sanitize($0) }
|
|
140
140
|
}
|
|
@@ -651,7 +651,7 @@ public final class ExpoIapOnsideModule: Module {
|
|
|
651
651
|
}
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
-
private func resolveSku(from request: RequestPurchaseProps) throws -> String {
|
|
654
|
+
nonisolated private func resolveSku(from request: RequestPurchaseProps) throws -> String {
|
|
655
655
|
let sku: String?
|
|
656
656
|
switch (request.type, request.request) {
|
|
657
657
|
case (.inApp, .purchase(let platforms)):
|
package/openiap-versions.json
CHANGED
package/osv-scanner.toml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
[[IgnoredVulns]]
|
|
2
|
+
id = "GHSA-5p2g-fcmc-qvqq"
|
|
3
|
+
ignoreUntil = 2026-09-14
|
|
4
|
+
reason = "No patched image-size release exists; Metro uses it only during trusted local builds."
|
|
5
|
+
|
|
6
|
+
[[IgnoredVulns]]
|
|
7
|
+
id = "GHSA-w3rx-r6r6-pgpr"
|
|
8
|
+
ignoreUntil = 2026-09-14
|
|
9
|
+
reason = "No patched image-size release exists; Metro uses it only during trusted local builds."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-iap",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.2",
|
|
4
4
|
"description": "In App Purchase module in Expo",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -59,14 +59,17 @@
|
|
|
59
59
|
"eslint-config-expo": "^57.0.1",
|
|
60
60
|
"eslint-config-prettier": "^10.1.8",
|
|
61
61
|
"eslint-plugin-prettier": "^5.5.6",
|
|
62
|
+
"expo": "^57.0.12",
|
|
62
63
|
"expo-module-scripts": "^56.0.3",
|
|
63
64
|
"expo-modules-core": "^57.0.10",
|
|
64
65
|
"globals": "^17.9.0",
|
|
65
66
|
"husky": "^9.1.7",
|
|
66
67
|
"jest": "^29.7.0",
|
|
67
68
|
"react": "19.2.3",
|
|
69
|
+
"react-native": "0.86.2",
|
|
68
70
|
"test-renderer": "^1.2.0",
|
|
69
|
-
"ts-jest": "^29.4.12"
|
|
71
|
+
"ts-jest": "^29.4.12",
|
|
72
|
+
"typescript": "^5.9.2"
|
|
70
73
|
},
|
|
71
74
|
"peerDependencies": {
|
|
72
75
|
"@amazon-devices/keplerscript-appstore-iap-lib": "~2.13.0",
|
|
@@ -83,6 +86,9 @@
|
|
|
83
86
|
"optional": true
|
|
84
87
|
}
|
|
85
88
|
},
|
|
89
|
+
"overrides": {
|
|
90
|
+
"uuid": "11.1.1"
|
|
91
|
+
},
|
|
86
92
|
"expo": {
|
|
87
93
|
"plugin": "./app.plugin.js"
|
|
88
94
|
}
|
package/plugin/build/withVega.js
CHANGED
|
@@ -42,6 +42,9 @@ const GENERATED_JS_MARKER = '// @generated by expo-iap';
|
|
|
42
42
|
const DEFAULT_ICON_FILE = 'icon.png';
|
|
43
43
|
const DEFAULT_BUILD_TYPE = 'Release';
|
|
44
44
|
const DEFAULT_RUNTIME_MODULE = '/com.amazon.kepler.keplerscript.runtime.loader_2@IKeplerScript_2_0';
|
|
45
|
+
// Vega SDK 0.24 requires both the OS module and an [os.version] block.
|
|
46
|
+
const VEGA_OS_MODULE = '/com.amazon.vega.os@IVega_1_2';
|
|
47
|
+
const VEGA_OS_VERSION = '1.2';
|
|
45
48
|
const logOnce = (() => {
|
|
46
49
|
const printed = new Set();
|
|
47
50
|
return (msg) => {
|
|
@@ -133,6 +136,13 @@ id = "/com.amazon.iap.core@IIAPCoreUI"
|
|
|
133
136
|
[needs]
|
|
134
137
|
[[needs.module]]
|
|
135
138
|
id = "/com.amazon.kepler.appstore.iap.purchase.core@IAppstoreIAPPurchaseCoreService"
|
|
139
|
+
|
|
140
|
+
[[needs.module]]
|
|
141
|
+
id = ${escapeTomlString(VEGA_OS_MODULE)}
|
|
142
|
+
|
|
143
|
+
[os.version]
|
|
144
|
+
target = ${escapeTomlString(VEGA_OS_VERSION)}
|
|
145
|
+
min = ${escapeTomlString(VEGA_OS_VERSION)}
|
|
136
146
|
`;
|
|
137
147
|
exports.createVegaManifest = createVegaManifest;
|
|
138
148
|
const createVegaEntryPoint = () => `${GENERATED_JS_MARKER}
|
package/plugin/src/withVega.ts
CHANGED
|
@@ -13,6 +13,9 @@ const DEFAULT_ICON_FILE = 'icon.png';
|
|
|
13
13
|
const DEFAULT_BUILD_TYPE = 'Release';
|
|
14
14
|
const DEFAULT_RUNTIME_MODULE =
|
|
15
15
|
'/com.amazon.kepler.keplerscript.runtime.loader_2@IKeplerScript_2_0';
|
|
16
|
+
// Vega SDK 0.24 requires both the OS module and an [os.version] block.
|
|
17
|
+
const VEGA_OS_MODULE = '/com.amazon.vega.os@IVega_1_2';
|
|
18
|
+
const VEGA_OS_VERSION = '1.2';
|
|
16
19
|
|
|
17
20
|
const logOnce = (() => {
|
|
18
21
|
const printed = new Set<string>();
|
|
@@ -155,6 +158,13 @@ id = "/com.amazon.iap.core@IIAPCoreUI"
|
|
|
155
158
|
[needs]
|
|
156
159
|
[[needs.module]]
|
|
157
160
|
id = "/com.amazon.kepler.appstore.iap.purchase.core@IAppstoreIAPPurchaseCoreService"
|
|
161
|
+
|
|
162
|
+
[[needs.module]]
|
|
163
|
+
id = ${escapeTomlString(VEGA_OS_MODULE)}
|
|
164
|
+
|
|
165
|
+
[os.version]
|
|
166
|
+
target = ${escapeTomlString(VEGA_OS_VERSION)}
|
|
167
|
+
min = ${escapeTomlString(VEGA_OS_VERSION)}
|
|
158
168
|
`;
|
|
159
169
|
|
|
160
170
|
export const createVegaEntryPoint = (): string => `${GENERATED_JS_MARKER}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
|
|
3
|
+
final class ExpoIapLogTests: XCTestCase {
|
|
4
|
+
override func tearDown() {
|
|
5
|
+
ExpoIapLog.setHandler(nil)
|
|
6
|
+
super.tearDown()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@objc func testNullSensitiveValuesAreOmittedAndPresentValuesAreMasked() {
|
|
10
|
+
var output = ""
|
|
11
|
+
ExpoIapLog.setEnabled(true)
|
|
12
|
+
ExpoIapLog.setHandler { _, message in output = message }
|
|
13
|
+
|
|
14
|
+
let payload: [String: Any?] = [
|
|
15
|
+
"purchaseToken": nil,
|
|
16
|
+
"userIdAmazon": NSNull(),
|
|
17
|
+
"apiKey": "known-api-key",
|
|
18
|
+
]
|
|
19
|
+
ExpoIapLog.payload("requestPurchase", payload: payload)
|
|
20
|
+
|
|
21
|
+
XCTAssertFalse(output.contains("purchaseToken"))
|
|
22
|
+
XCTAssertFalse(output.contains("userIdAmazon"))
|
|
23
|
+
XCTAssertTrue(output.contains("\"apiKey\":\"hidden\""))
|
|
24
|
+
XCTAssertFalse(output.contains("known-api-key"))
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@main
|
|
29
|
+
private enum ExpoIapLogTestRunner {
|
|
30
|
+
static func main() {
|
|
31
|
+
let test = ExpoIapLogTests(
|
|
32
|
+
selector: #selector(ExpoIapLogTests.testNullSensitiveValuesAreOmittedAndPresentValuesAreMasked)
|
|
33
|
+
)
|
|
34
|
+
test.run()
|
|
35
|
+
precondition(test.testRun?.hasSucceeded == true)
|
|
36
|
+
}
|
|
37
|
+
}
|