expo-iap 3.0.0 → 3.0.1
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/CHANGELOG.md +6 -0
- package/README.md +9 -1
- package/android/build.gradle +1 -1
- package/package.json +1 -1
- package/plugin/build/withIAP.js +17 -11
- package/plugin/build/withLocalOpenIAP.js +11 -7
- package/plugin/src/withIAP.ts +24 -16
- package/plugin/src/withLocalOpenIAP.ts +11 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 3.0.1 - 2025-09-13
|
|
4
|
+
|
|
5
|
+
- Android: Ensure `openiap-google:1.1.0` is added inside `dependencies {}` and replace/dedupe existing entries. In local dev, remove the Maven line and rely on `project(':openiap-google')`. Library fallback bumped to 1.1.0.
|
|
6
|
+
- iOS: Honor `enableLocalDev: false` even when `localPath` is set. Ensure CocoaPods CDN in Podfile and remove any stale local `pod 'openiap', :path => ...` lines.
|
|
7
|
+
- Misc: Drop legacy Billing/GMS cleanup patterns, simplify prebuild logs, and add a short release blog post.
|
|
8
|
+
|
|
3
9
|
## 3.0.0 - 2025-09-13
|
|
4
10
|
|
|
5
11
|
Breaking changes:
|
package/README.md
CHANGED
|
@@ -16,7 +16,15 @@
|
|
|
16
16
|
|
|
17
17
|
## Notice
|
|
18
18
|
|
|
19
|
-
The `expo-iap` module has been migrated from [react-native-iap](https://github.com/dooboolab/react-native-iap).
|
|
19
|
+
The `expo-iap` module has been migrated from [react-native-iap](https://github.com/dooboolab/react-native-iap). While we initially considered fully merging everything into `react-native-iap`, we ultimately decided to maintain the two libraries in parallel, each tailored to its own ecosystem.
|
|
20
|
+
|
|
21
|
+
- **`react-native-iap`** → a **Nitro Modules–based** implementation for React Native.
|
|
22
|
+
- **`expo-iap`** → an **Expo Module** with tighter integration and smoother compatibility in the Expo ecosystem.
|
|
23
|
+
|
|
24
|
+
Both libraries will continue to be maintained in parallel going forward.
|
|
25
|
+
|
|
26
|
+
📖 See the [Future Roadmap and Discussion](https://github.com/dooboolab-community/react-native-iap/discussions/2754) for more details.
|
|
27
|
+
👉 Stay updated via the [Current Project Status comment](https://github.com/dooboolab-community/react-native-iap/discussions/2754#discussioncomment-10510249).
|
|
20
28
|
|
|
21
29
|
## Installation
|
|
22
30
|
|
package/android/build.gradle
CHANGED
|
@@ -58,6 +58,6 @@ dependencies {
|
|
|
58
58
|
implementation project(":openiap-google")
|
|
59
59
|
} else {
|
|
60
60
|
// Fallback to published artifact when local project isn't linked
|
|
61
|
-
implementation "io.github.hyochan.openiap:openiap-google:1.0
|
|
61
|
+
implementation "io.github.hyochan.openiap:openiap-google:1.1.0"
|
|
62
62
|
}
|
|
63
63
|
}
|
package/package.json
CHANGED
package/plugin/build/withIAP.js
CHANGED
|
@@ -65,21 +65,26 @@ const addLineToGradle = (content, anchor, lineToAdd, offset = 1) => {
|
|
|
65
65
|
};
|
|
66
66
|
const modifyAppBuildGradle = (gradle, language) => {
|
|
67
67
|
let modified = gradle;
|
|
68
|
-
//
|
|
68
|
+
// Ensure OpenIAP dependency exists at desired version in app-level build.gradle(.kts)
|
|
69
69
|
const impl = (ga, v) => language === 'kotlin'
|
|
70
70
|
? ` implementation("${ga}:${v}")`
|
|
71
71
|
: ` implementation "${ga}:${v}"`;
|
|
72
72
|
// Pin OpenIAP Google library to 1.1.0
|
|
73
73
|
const openiapDep = impl('io.github.hyochan.openiap:openiap-google', '1.1.0');
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
// Remove any existing openiap-google lines (any version, groovy/kotlin, implementation/api)
|
|
75
|
+
const openiapAnyLine = /^\s*(?:implementation|api)\s*\(?\s*["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*\)?\s*$/gm;
|
|
76
|
+
const hadExisting = openiapAnyLine.test(modified);
|
|
77
|
+
if (hadExisting) {
|
|
78
|
+
modified = modified.replace(openiapAnyLine, '').replace(/\n{3,}/g, '\n\n');
|
|
79
|
+
}
|
|
80
|
+
// Ensure the desired dependency line is present
|
|
81
|
+
if (!new RegExp(String.raw `io\.github\.hyochan\.openiap:openiap-google:1\.1\.0`).test(modified)) {
|
|
82
|
+
// Insert just after the opening `dependencies {` line
|
|
83
|
+
modified = addLineToGradle(modified, /dependencies\s*{/, openiapDep, 1);
|
|
84
|
+
logOnce(hadExisting
|
|
85
|
+
? '🛠️ expo-iap: Replaced OpenIAP dependency with 1.1.0'
|
|
86
|
+
: '🛠️ expo-iap: Added OpenIAP dependency (1.1.0) to build.gradle');
|
|
79
87
|
}
|
|
80
|
-
// Log only once and only if we actually added dependencies
|
|
81
|
-
if (hasAddedDependency)
|
|
82
|
-
logOnce('🛠️ expo-iap: Added OpenIAP dependency to build.gradle');
|
|
83
88
|
return modified;
|
|
84
89
|
};
|
|
85
90
|
const withIapAndroid = (config, props) => {
|
|
@@ -141,11 +146,12 @@ const withIapIOS = (config) => {
|
|
|
141
146
|
};
|
|
142
147
|
const withIap = (config, options) => {
|
|
143
148
|
try {
|
|
144
|
-
|
|
149
|
+
// Respect explicit flag; fall back to presence of localPath only when flag is unset
|
|
150
|
+
const isLocalDev = options?.enableLocalDev ?? !!options?.localPath;
|
|
145
151
|
// Apply Android modifications (skip adding deps when linking local module)
|
|
146
152
|
let result = withIapAndroid(config, { addDeps: !isLocalDev });
|
|
147
153
|
// iOS: choose one path to avoid overlap
|
|
148
|
-
if (
|
|
154
|
+
if (isLocalDev) {
|
|
149
155
|
if (!options?.localPath) {
|
|
150
156
|
config_plugins_1.WarningAggregator.addWarningIOS('expo-iap', 'enableLocalDev is true but no localPath provided. Skipping local OpenIAP integration.');
|
|
151
157
|
}
|
|
@@ -177,10 +177,12 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
177
177
|
}
|
|
178
178
|
const gradle = config.modResults;
|
|
179
179
|
const dependencyLine = ` implementation project(':openiap-google')`;
|
|
180
|
-
// Remove any previously
|
|
180
|
+
// Remove any previously added Maven deps for openiap-google to avoid duplicate classes
|
|
181
181
|
const removalPatterns = [
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
// Groovy DSL: implementation "io.github.hyochan.openiap:openiap-google:x.y.z" or api "..."
|
|
183
|
+
/^\s*(?:implementation|api)\s+["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*$/gm,
|
|
184
|
+
// Kotlin DSL: implementation("io.github.hyochan.openiap:openiap-google:x.y.z") or api("...")
|
|
185
|
+
/^\s*(?:implementation|api)\s*\(\s*["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*\)\s*$/gm,
|
|
184
186
|
];
|
|
185
187
|
let contents = gradle.contents;
|
|
186
188
|
let removedAny = false;
|
|
@@ -192,7 +194,7 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
192
194
|
}
|
|
193
195
|
if (removedAny) {
|
|
194
196
|
gradle.contents = contents;
|
|
195
|
-
console.log('🧹 Removed
|
|
197
|
+
console.log('🧹 Removed Maven openiap-google to use local :openiap-google');
|
|
196
198
|
}
|
|
197
199
|
if (!gradle.contents.includes(dependencyLine)) {
|
|
198
200
|
const anchor = /dependencies\s*\{/m;
|
|
@@ -216,8 +218,10 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
216
218
|
if (fs.existsSync(appBuildGradle)) {
|
|
217
219
|
let contents = fs.readFileSync(appBuildGradle, 'utf8');
|
|
218
220
|
const patterns = [
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
// Groovy DSL
|
|
222
|
+
/^\s*(?:implementation|api)\s+["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*$/gm,
|
|
223
|
+
// Kotlin DSL
|
|
224
|
+
/^\s*(?:implementation|api)\s*\(\s*["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*\)\s*$/gm,
|
|
221
225
|
];
|
|
222
226
|
let changed = false;
|
|
223
227
|
for (const p of patterns) {
|
|
@@ -228,7 +232,7 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
228
232
|
}
|
|
229
233
|
if (changed) {
|
|
230
234
|
fs.writeFileSync(appBuildGradle, contents);
|
|
231
|
-
console.log('🧹 expo-iap: Cleaned
|
|
235
|
+
console.log('🧹 expo-iap: Cleaned Maven openiap-google for local :openiap-google');
|
|
232
236
|
}
|
|
233
237
|
}
|
|
234
238
|
}
|
package/plugin/src/withIAP.ts
CHANGED
|
@@ -49,7 +49,7 @@ const modifyAppBuildGradle = (
|
|
|
49
49
|
): string => {
|
|
50
50
|
let modified = gradle;
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// Ensure OpenIAP dependency exists at desired version in app-level build.gradle(.kts)
|
|
53
53
|
const impl = (ga: string, v: string) =>
|
|
54
54
|
language === 'kotlin'
|
|
55
55
|
? ` implementation("${ga}:${v}")`
|
|
@@ -57,21 +57,28 @@ const modifyAppBuildGradle = (
|
|
|
57
57
|
// Pin OpenIAP Google library to 1.1.0
|
|
58
58
|
const openiapDep = impl('io.github.hyochan.openiap:openiap-google', '1.1.0');
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (!hasGA('io.github.hyochan.openiap:openiap-google')) {
|
|
68
|
-
modified = addLineToGradle(modified, /dependencies\s*{/, openiapDep, 0);
|
|
69
|
-
hasAddedDependency = true;
|
|
60
|
+
// Remove any existing openiap-google lines (any version, groovy/kotlin, implementation/api)
|
|
61
|
+
const openiapAnyLine =
|
|
62
|
+
/^\s*(?:implementation|api)\s*\(?\s*["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*\)?\s*$/gm;
|
|
63
|
+
const hadExisting = openiapAnyLine.test(modified);
|
|
64
|
+
if (hadExisting) {
|
|
65
|
+
modified = modified.replace(openiapAnyLine, '').replace(/\n{3,}/g, '\n\n');
|
|
70
66
|
}
|
|
71
67
|
|
|
72
|
-
//
|
|
73
|
-
if (
|
|
74
|
-
|
|
68
|
+
// Ensure the desired dependency line is present
|
|
69
|
+
if (
|
|
70
|
+
!new RegExp(
|
|
71
|
+
String.raw`io\.github\.hyochan\.openiap:openiap-google:1\.1\.0`,
|
|
72
|
+
).test(modified)
|
|
73
|
+
) {
|
|
74
|
+
// Insert just after the opening `dependencies {` line
|
|
75
|
+
modified = addLineToGradle(modified, /dependencies\s*{/, openiapDep, 1);
|
|
76
|
+
logOnce(
|
|
77
|
+
hadExisting
|
|
78
|
+
? '🛠️ expo-iap: Replaced OpenIAP dependency with 1.1.0'
|
|
79
|
+
: '🛠️ expo-iap: Added OpenIAP dependency (1.1.0) to build.gradle',
|
|
80
|
+
);
|
|
81
|
+
}
|
|
75
82
|
|
|
76
83
|
return modified;
|
|
77
84
|
};
|
|
@@ -173,12 +180,13 @@ const withIap: ConfigPlugin<ExpoIapPluginOptions | void> = (
|
|
|
173
180
|
options,
|
|
174
181
|
) => {
|
|
175
182
|
try {
|
|
176
|
-
|
|
183
|
+
// Respect explicit flag; fall back to presence of localPath only when flag is unset
|
|
184
|
+
const isLocalDev = options?.enableLocalDev ?? !!options?.localPath;
|
|
177
185
|
// Apply Android modifications (skip adding deps when linking local module)
|
|
178
186
|
let result = withIapAndroid(config, {addDeps: !isLocalDev});
|
|
179
187
|
|
|
180
188
|
// iOS: choose one path to avoid overlap
|
|
181
|
-
if (
|
|
189
|
+
if (isLocalDev) {
|
|
182
190
|
if (!options?.localPath) {
|
|
183
191
|
WarningAggregator.addWarningIOS(
|
|
184
192
|
'expo-iap',
|
|
@@ -196,10 +196,12 @@ const withLocalOpenIAP: ConfigPlugin<{localPath?: LocalPathOption} | void> = (
|
|
|
196
196
|
const gradle = config.modResults;
|
|
197
197
|
const dependencyLine = ` implementation project(':openiap-google')`;
|
|
198
198
|
|
|
199
|
-
// Remove any previously
|
|
199
|
+
// Remove any previously added Maven deps for openiap-google to avoid duplicate classes
|
|
200
200
|
const removalPatterns = [
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
// Groovy DSL: implementation "io.github.hyochan.openiap:openiap-google:x.y.z" or api "..."
|
|
202
|
+
/^\s*(?:implementation|api)\s+["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*$/gm,
|
|
203
|
+
// Kotlin DSL: implementation("io.github.hyochan.openiap:openiap-google:x.y.z") or api("...")
|
|
204
|
+
/^\s*(?:implementation|api)\s*\(\s*["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*\)\s*$/gm,
|
|
203
205
|
];
|
|
204
206
|
let contents = gradle.contents;
|
|
205
207
|
let removedAny = false;
|
|
@@ -212,7 +214,7 @@ const withLocalOpenIAP: ConfigPlugin<{localPath?: LocalPathOption} | void> = (
|
|
|
212
214
|
if (removedAny) {
|
|
213
215
|
gradle.contents = contents;
|
|
214
216
|
console.log(
|
|
215
|
-
'🧹 Removed
|
|
217
|
+
'🧹 Removed Maven openiap-google to use local :openiap-google',
|
|
216
218
|
);
|
|
217
219
|
}
|
|
218
220
|
if (!gradle.contents.includes(dependencyLine)) {
|
|
@@ -244,8 +246,10 @@ const withLocalOpenIAP: ConfigPlugin<{localPath?: LocalPathOption} | void> = (
|
|
|
244
246
|
if (fs.existsSync(appBuildGradle)) {
|
|
245
247
|
let contents = fs.readFileSync(appBuildGradle, 'utf8');
|
|
246
248
|
const patterns = [
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
// Groovy DSL
|
|
250
|
+
/^\s*(?:implementation|api)\s+["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*$/gm,
|
|
251
|
+
// Kotlin DSL
|
|
252
|
+
/^\s*(?:implementation|api)\s*\(\s*["']io\.github\.hyochan\.openiap:openiap-google:[^"']+["']\s*\)\s*$/gm,
|
|
249
253
|
];
|
|
250
254
|
let changed = false;
|
|
251
255
|
for (const p of patterns) {
|
|
@@ -257,7 +261,7 @@ const withLocalOpenIAP: ConfigPlugin<{localPath?: LocalPathOption} | void> = (
|
|
|
257
261
|
if (changed) {
|
|
258
262
|
fs.writeFileSync(appBuildGradle, contents);
|
|
259
263
|
console.log(
|
|
260
|
-
'🧹 expo-iap: Cleaned
|
|
264
|
+
'🧹 expo-iap: Cleaned Maven openiap-google for local :openiap-google',
|
|
261
265
|
);
|
|
262
266
|
}
|
|
263
267
|
}
|