expo-iap 4.3.2 → 4.3.3
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/package.json
CHANGED
|
@@ -8,6 +8,8 @@ type LocalPathOption = string | {
|
|
|
8
8
|
ios?: string;
|
|
9
9
|
android?: string;
|
|
10
10
|
};
|
|
11
|
+
type GradleLanguage = 'groovy' | 'kotlin';
|
|
12
|
+
export declare const ensureLocalOpenIapFlavorStrategy: (contents: string, flavor: "play" | "horizon", language?: GradleLanguage) => string;
|
|
11
13
|
declare const withLocalOpenIAP: ConfigPlugin<{
|
|
12
14
|
localPath?: LocalPathOption;
|
|
13
15
|
iosAlternativeBilling?: IOSAlternativeBillingConfig;
|
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ensureLocalOpenIapFlavorStrategy = void 0;
|
|
36
37
|
const config_plugins_1 = require("expo/config-plugins");
|
|
37
38
|
const fs = __importStar(require("fs"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
@@ -72,6 +73,42 @@ const logOnce = (() => {
|
|
|
72
73
|
}
|
|
73
74
|
};
|
|
74
75
|
})();
|
|
76
|
+
const LOCAL_OPENIAP_FLAVOR_BLOCK_START = '// Added by expo-iap (local openiap-google flavor selection)';
|
|
77
|
+
const LOCAL_OPENIAP_FLAVOR_BLOCK_END = '// End expo-iap local openiap-google flavor selection';
|
|
78
|
+
const normalizeGradleLanguage = (language) => language === 'kotlin' ? 'kotlin' : 'groovy';
|
|
79
|
+
const ensureLocalOpenIapFlavorStrategy = (contents, flavor, language = 'groovy') => {
|
|
80
|
+
const existingBlockPattern = new RegExp(`\\n?${escapeRegExp(LOCAL_OPENIAP_FLAVOR_BLOCK_START)}[\\s\\S]*?${escapeRegExp(LOCAL_OPENIAP_FLAVOR_BLOCK_END)}\\n?`, 'gm');
|
|
81
|
+
const cleaned = contents
|
|
82
|
+
.replace(existingBlockPattern, '\n')
|
|
83
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
84
|
+
.trimEnd();
|
|
85
|
+
const strategyBlock = language === 'kotlin'
|
|
86
|
+
? `subprojects {
|
|
87
|
+
plugins.withId("com.android.library") {
|
|
88
|
+
extensions.configure<com.android.build.gradle.LibraryExtension>("android") {
|
|
89
|
+
defaultConfig {
|
|
90
|
+
missingDimensionStrategy("platform", "${flavor}")
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}`
|
|
95
|
+
: `subprojects { subproject ->
|
|
96
|
+
subproject.plugins.withId("com.android.library") {
|
|
97
|
+
subproject.android {
|
|
98
|
+
defaultConfig {
|
|
99
|
+
missingDimensionStrategy "platform", "${flavor}"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}`;
|
|
104
|
+
return `${cleaned}
|
|
105
|
+
|
|
106
|
+
${LOCAL_OPENIAP_FLAVOR_BLOCK_START}
|
|
107
|
+
${strategyBlock}
|
|
108
|
+
${LOCAL_OPENIAP_FLAVOR_BLOCK_END}
|
|
109
|
+
`;
|
|
110
|
+
};
|
|
111
|
+
exports.ensureLocalOpenIapFlavorStrategy = ensureLocalOpenIapFlavorStrategy;
|
|
75
112
|
const withLocalOpenIAP = (config, props) => {
|
|
76
113
|
// Import and apply iOS alternative billing configuration if provided
|
|
77
114
|
if (props?.iosAlternativeBilling) {
|
|
@@ -162,9 +199,15 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
162
199
|
.replace(/\\/g, '/');
|
|
163
200
|
// 1) settings.gradle: include and map projectDir
|
|
164
201
|
const settings = config.modResults;
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
202
|
+
const settingsLanguage = normalizeGradleLanguage(settings.language);
|
|
203
|
+
const includeLine = settingsLanguage === 'kotlin'
|
|
204
|
+
? 'include(":openiap-google")'
|
|
205
|
+
: "include ':openiap-google'";
|
|
206
|
+
const projectDirLine = settingsLanguage === 'kotlin'
|
|
207
|
+
? `project(":openiap-google").projectDir = File(settingsDir, "${relativeAndroidModulePath}")`
|
|
208
|
+
: `project(':openiap-google').projectDir = new File(settingsDir, '${relativeAndroidModulePath}')`;
|
|
209
|
+
const includePattern = /include\s*(?:\(\s*)?["']:openiap-google["']\s*\)?/;
|
|
210
|
+
const projectDirPattern = /^\s*project\(["']:openiap-google["']\)\.projectDir\s*=.*$/gm;
|
|
168
211
|
let contents = settings.contents ?? '';
|
|
169
212
|
// Ensure pluginManagement has plugin mappings required by the included module
|
|
170
213
|
const injectPluginManagement = () => {
|
|
@@ -208,7 +251,7 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
208
251
|
}
|
|
209
252
|
};
|
|
210
253
|
injectPluginManagement();
|
|
211
|
-
if (!
|
|
254
|
+
if (!includePattern.test(contents))
|
|
212
255
|
contents += `\n${includeLine}\n`;
|
|
213
256
|
if (projectDirPattern.test(contents)) {
|
|
214
257
|
contents = contents.replace(projectDirPattern, projectDirLine);
|
|
@@ -232,9 +275,14 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
232
275
|
return config;
|
|
233
276
|
}
|
|
234
277
|
const gradle = config.modResults;
|
|
235
|
-
const
|
|
278
|
+
const appLanguage = normalizeGradleLanguage(gradle.language);
|
|
279
|
+
const dependencyLine = appLanguage === 'kotlin'
|
|
280
|
+
? ` implementation(project(":openiap-google"))`
|
|
281
|
+
: ` implementation project(':openiap-google')`;
|
|
236
282
|
const flavor = props?.isHorizonEnabled ? 'horizon' : 'play';
|
|
237
|
-
const strategyLine =
|
|
283
|
+
const strategyLine = appLanguage === 'kotlin'
|
|
284
|
+
? ` missingDimensionStrategy("platform", "${flavor}")`
|
|
285
|
+
: ` missingDimensionStrategy "platform", "${flavor}"`;
|
|
238
286
|
let contents = gradle.contents;
|
|
239
287
|
// Remove Maven deps (both openiap-google and openiap-google-horizon)
|
|
240
288
|
// to avoid duplicate classes with local module
|
|
@@ -273,6 +321,23 @@ const withLocalOpenIAP = (config, props) => {
|
|
|
273
321
|
gradle.contents = contents;
|
|
274
322
|
return config;
|
|
275
323
|
});
|
|
324
|
+
// 2b) project build.gradle: Expo autolinked library modules can consume the
|
|
325
|
+
// local flavored OpenIAP module transitively, so give them the same default.
|
|
326
|
+
config = (0, config_plugins_1.withProjectBuildGradle)(config, (config) => {
|
|
327
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
328
|
+
const raw = props?.localPath;
|
|
329
|
+
const androidInput = typeof raw === 'string' ? undefined : raw?.android;
|
|
330
|
+
const androidModulePath = resolveAndroidModulePath(androidInput) ||
|
|
331
|
+
resolveAndroidModulePath(path.resolve(projectRoot, 'openiap-google')) ||
|
|
332
|
+
null;
|
|
333
|
+
if (!androidModulePath || !fs.existsSync(androidModulePath)) {
|
|
334
|
+
return config;
|
|
335
|
+
}
|
|
336
|
+
const flavor = props?.isHorizonEnabled ? 'horizon' : 'play';
|
|
337
|
+
config.modResults.contents = (0, exports.ensureLocalOpenIapFlavorStrategy)(config.modResults.contents, flavor, normalizeGradleLanguage(config.modResults.language));
|
|
338
|
+
logOnce(`🛠️ expo-iap: Added local OpenIAP flavor strategy for ${flavor}`);
|
|
339
|
+
return config;
|
|
340
|
+
});
|
|
276
341
|
// 3) Set horizonEnabled in gradle.properties
|
|
277
342
|
config = (0, config_plugins_1.withDangerousMod)(config, [
|
|
278
343
|
'android',
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
withDangerousMod,
|
|
4
4
|
withSettingsGradle,
|
|
5
5
|
withAppBuildGradle,
|
|
6
|
+
withProjectBuildGradle,
|
|
6
7
|
} from 'expo/config-plugins';
|
|
7
8
|
import * as fs from 'fs';
|
|
8
9
|
import * as path from 'path';
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
* This is only for local development with openiap-apple library
|
|
17
18
|
*/
|
|
18
19
|
type LocalPathOption = string | {ios?: string; android?: string};
|
|
20
|
+
type GradleLanguage = 'groovy' | 'kotlin';
|
|
19
21
|
|
|
20
22
|
interface AndroidGradlePluginVersions {
|
|
21
23
|
kotlin: string;
|
|
@@ -86,6 +88,59 @@ const logOnce = (() => {
|
|
|
86
88
|
};
|
|
87
89
|
})();
|
|
88
90
|
|
|
91
|
+
const LOCAL_OPENIAP_FLAVOR_BLOCK_START =
|
|
92
|
+
'// Added by expo-iap (local openiap-google flavor selection)';
|
|
93
|
+
const LOCAL_OPENIAP_FLAVOR_BLOCK_END =
|
|
94
|
+
'// End expo-iap local openiap-google flavor selection';
|
|
95
|
+
|
|
96
|
+
const normalizeGradleLanguage = (language?: string): GradleLanguage =>
|
|
97
|
+
language === 'kotlin' ? 'kotlin' : 'groovy';
|
|
98
|
+
|
|
99
|
+
export const ensureLocalOpenIapFlavorStrategy = (
|
|
100
|
+
contents: string,
|
|
101
|
+
flavor: 'play' | 'horizon',
|
|
102
|
+
language: GradleLanguage = 'groovy',
|
|
103
|
+
): string => {
|
|
104
|
+
const existingBlockPattern = new RegExp(
|
|
105
|
+
`\\n?${escapeRegExp(
|
|
106
|
+
LOCAL_OPENIAP_FLAVOR_BLOCK_START,
|
|
107
|
+
)}[\\s\\S]*?${escapeRegExp(LOCAL_OPENIAP_FLAVOR_BLOCK_END)}\\n?`,
|
|
108
|
+
'gm',
|
|
109
|
+
);
|
|
110
|
+
const cleaned = contents
|
|
111
|
+
.replace(existingBlockPattern, '\n')
|
|
112
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
113
|
+
.trimEnd();
|
|
114
|
+
|
|
115
|
+
const strategyBlock =
|
|
116
|
+
language === 'kotlin'
|
|
117
|
+
? `subprojects {
|
|
118
|
+
plugins.withId("com.android.library") {
|
|
119
|
+
extensions.configure<com.android.build.gradle.LibraryExtension>("android") {
|
|
120
|
+
defaultConfig {
|
|
121
|
+
missingDimensionStrategy("platform", "${flavor}")
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}`
|
|
126
|
+
: `subprojects { subproject ->
|
|
127
|
+
subproject.plugins.withId("com.android.library") {
|
|
128
|
+
subproject.android {
|
|
129
|
+
defaultConfig {
|
|
130
|
+
missingDimensionStrategy "platform", "${flavor}"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}`;
|
|
135
|
+
|
|
136
|
+
return `${cleaned}
|
|
137
|
+
|
|
138
|
+
${LOCAL_OPENIAP_FLAVOR_BLOCK_START}
|
|
139
|
+
${strategyBlock}
|
|
140
|
+
${LOCAL_OPENIAP_FLAVOR_BLOCK_END}
|
|
141
|
+
`;
|
|
142
|
+
};
|
|
143
|
+
|
|
89
144
|
const withLocalOpenIAP: ConfigPlugin<
|
|
90
145
|
{
|
|
91
146
|
localPath?: LocalPathOption;
|
|
@@ -203,10 +258,18 @@ const withLocalOpenIAP: ConfigPlugin<
|
|
|
203
258
|
|
|
204
259
|
// 1) settings.gradle: include and map projectDir
|
|
205
260
|
const settings = config.modResults;
|
|
206
|
-
const
|
|
207
|
-
const
|
|
261
|
+
const settingsLanguage = normalizeGradleLanguage(settings.language);
|
|
262
|
+
const includeLine =
|
|
263
|
+
settingsLanguage === 'kotlin'
|
|
264
|
+
? 'include(":openiap-google")'
|
|
265
|
+
: "include ':openiap-google'";
|
|
266
|
+
const projectDirLine =
|
|
267
|
+
settingsLanguage === 'kotlin'
|
|
268
|
+
? `project(":openiap-google").projectDir = File(settingsDir, "${relativeAndroidModulePath}")`
|
|
269
|
+
: `project(':openiap-google').projectDir = new File(settingsDir, '${relativeAndroidModulePath}')`;
|
|
270
|
+
const includePattern = /include\s*(?:\(\s*)?["']:openiap-google["']\s*\)?/;
|
|
208
271
|
const projectDirPattern =
|
|
209
|
-
|
|
272
|
+
/^\s*project\(["']:openiap-google["']\)\.projectDir\s*=.*$/gm;
|
|
210
273
|
let contents = settings.contents ?? '';
|
|
211
274
|
|
|
212
275
|
// Ensure pluginManagement has plugin mappings required by the included module
|
|
@@ -279,7 +342,7 @@ const withLocalOpenIAP: ConfigPlugin<
|
|
|
279
342
|
};
|
|
280
343
|
|
|
281
344
|
injectPluginManagement();
|
|
282
|
-
if (!
|
|
345
|
+
if (!includePattern.test(contents)) contents += `\n${includeLine}\n`;
|
|
283
346
|
if (projectDirPattern.test(contents)) {
|
|
284
347
|
contents = contents.replace(projectDirPattern, projectDirLine);
|
|
285
348
|
} else if (!contents.includes(projectDirLine)) {
|
|
@@ -305,9 +368,16 @@ const withLocalOpenIAP: ConfigPlugin<
|
|
|
305
368
|
}
|
|
306
369
|
|
|
307
370
|
const gradle = config.modResults;
|
|
308
|
-
const
|
|
371
|
+
const appLanguage = normalizeGradleLanguage(gradle.language);
|
|
372
|
+
const dependencyLine =
|
|
373
|
+
appLanguage === 'kotlin'
|
|
374
|
+
? ` implementation(project(":openiap-google"))`
|
|
375
|
+
: ` implementation project(':openiap-google')`;
|
|
309
376
|
const flavor = props?.isHorizonEnabled ? 'horizon' : 'play';
|
|
310
|
-
const strategyLine =
|
|
377
|
+
const strategyLine =
|
|
378
|
+
appLanguage === 'kotlin'
|
|
379
|
+
? ` missingDimensionStrategy("platform", "${flavor}")`
|
|
380
|
+
: ` missingDimensionStrategy "platform", "${flavor}"`;
|
|
311
381
|
|
|
312
382
|
let contents = gradle.contents;
|
|
313
383
|
|
|
@@ -358,6 +428,31 @@ const withLocalOpenIAP: ConfigPlugin<
|
|
|
358
428
|
return config;
|
|
359
429
|
});
|
|
360
430
|
|
|
431
|
+
// 2b) project build.gradle: Expo autolinked library modules can consume the
|
|
432
|
+
// local flavored OpenIAP module transitively, so give them the same default.
|
|
433
|
+
config = withProjectBuildGradle(config, (config) => {
|
|
434
|
+
const projectRoot = (config.modRequest as any).projectRoot as string;
|
|
435
|
+
const raw = props?.localPath;
|
|
436
|
+
const androidInput = typeof raw === 'string' ? undefined : raw?.android;
|
|
437
|
+
const androidModulePath =
|
|
438
|
+
resolveAndroidModulePath(androidInput) ||
|
|
439
|
+
resolveAndroidModulePath(path.resolve(projectRoot, 'openiap-google')) ||
|
|
440
|
+
null;
|
|
441
|
+
|
|
442
|
+
if (!androidModulePath || !fs.existsSync(androidModulePath)) {
|
|
443
|
+
return config;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const flavor = props?.isHorizonEnabled ? 'horizon' : 'play';
|
|
447
|
+
config.modResults.contents = ensureLocalOpenIapFlavorStrategy(
|
|
448
|
+
config.modResults.contents,
|
|
449
|
+
flavor,
|
|
450
|
+
normalizeGradleLanguage(config.modResults.language),
|
|
451
|
+
);
|
|
452
|
+
logOnce(`🛠️ expo-iap: Added local OpenIAP flavor strategy for ${flavor}`);
|
|
453
|
+
return config;
|
|
454
|
+
});
|
|
455
|
+
|
|
361
456
|
// 3) Set horizonEnabled in gradle.properties
|
|
362
457
|
config = withDangerousMod(config, [
|
|
363
458
|
'android',
|