react-native-iap 15.3.6 → 15.4.0-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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/android/build.gradle +13 -5
  3. package/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.kt +19 -6
  4. package/ios/HybridRnIap.swift +13 -1
  5. package/lib/module/index.js +56 -16
  6. package/lib/module/index.js.map +1 -1
  7. package/lib/module/index.kepler.js +170 -0
  8. package/lib/module/index.kepler.js.map +1 -0
  9. package/lib/module/types/amazon-devices-kepler/index.d.js +2 -0
  10. package/lib/module/types/amazon-devices-kepler/index.d.js.map +1 -0
  11. package/lib/module/types.js +5 -2
  12. package/lib/module/types.js.map +1 -1
  13. package/lib/module/utils/error.js +2 -2
  14. package/lib/module/utils/error.js.map +1 -1
  15. package/lib/module/utils/type-bridge.js +4 -1
  16. package/lib/module/utils/type-bridge.js.map +1 -1
  17. package/lib/module/vega-adapter.js +981 -0
  18. package/lib/module/vega-adapter.js.map +1 -0
  19. package/lib/module/vega.js +10 -0
  20. package/lib/module/vega.js.map +1 -0
  21. package/lib/module/vega.kepler.js +18 -0
  22. package/lib/module/vega.kepler.js.map +1 -0
  23. package/lib/typescript/src/index.d.ts +9 -2
  24. package/lib/typescript/src/index.d.ts.map +1 -1
  25. package/lib/typescript/src/index.kepler.d.ts +55 -0
  26. package/lib/typescript/src/index.kepler.d.ts.map +1 -0
  27. package/lib/typescript/src/specs/RnIap.nitro.d.ts +10 -1
  28. package/lib/typescript/src/specs/RnIap.nitro.d.ts.map +1 -1
  29. package/lib/typescript/src/types.d.ts +16 -3
  30. package/lib/typescript/src/types.d.ts.map +1 -1
  31. package/lib/typescript/src/utils/type-bridge.d.ts.map +1 -1
  32. package/lib/typescript/src/vega-adapter.d.ts +76 -0
  33. package/lib/typescript/src/vega-adapter.d.ts.map +1 -0
  34. package/lib/typescript/src/vega.d.ts +4 -0
  35. package/lib/typescript/src/vega.d.ts.map +1 -0
  36. package/lib/typescript/src/vega.kepler.d.ts +4 -0
  37. package/lib/typescript/src/vega.kepler.d.ts.map +1 -0
  38. package/nitrogen/generated/android/NitroIap+autolinking.cmake +1 -0
  39. package/nitrogen/generated/android/c++/JHybridRnIapSpec.cpp +5 -0
  40. package/nitrogen/generated/android/c++/JIapStore.hpp +3 -0
  41. package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithIapkitAmazonProps.hpp +71 -0
  42. package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithIapkitProps.hpp +9 -1
  43. package/nitrogen/generated/android/c++/JNitroVerifyPurchaseWithProviderProps.hpp +4 -0
  44. package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.cpp +26 -0
  45. package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.hpp +75 -0
  46. package/nitrogen/generated/android/c++/JVariant_NullType_NitroVerifyPurchaseWithIapkitProps.hpp +4 -0
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/IapStore.kt +2 -1
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroVerifyPurchaseWithIapkitAmazonProps.kt +44 -0
  49. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/NitroVerifyPurchaseWithIapkitProps.kt +5 -2
  50. package/nitrogen/generated/android/kotlin/com/margelo/nitro/iap/Variant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.kt +53 -0
  51. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Bridge.hpp +47 -0
  52. package/nitrogen/generated/ios/NitroIap-Swift-Cxx-Umbrella.hpp +3 -0
  53. package/nitrogen/generated/ios/c++/HybridRnIapSpecSwift.hpp +3 -0
  54. package/nitrogen/generated/ios/swift/IapStore.swift +4 -0
  55. package/nitrogen/generated/ios/swift/NitroVerifyPurchaseWithIapkitAmazonProps.swift +103 -0
  56. package/nitrogen/generated/ios/swift/NitroVerifyPurchaseWithIapkitProps.swift +38 -1
  57. package/nitrogen/generated/ios/swift/Variant_NullType_NitroVerifyPurchaseWithIapkitAmazonProps.swift +18 -0
  58. package/nitrogen/generated/shared/c++/IapStore.hpp +4 -0
  59. package/nitrogen/generated/shared/c++/NitroVerifyPurchaseWithIapkitAmazonProps.hpp +94 -0
  60. package/nitrogen/generated/shared/c++/NitroVerifyPurchaseWithIapkitProps.hpp +8 -1
  61. package/openiap-versions.json +2 -2
  62. package/package.json +19 -12
  63. package/src/index.kepler.ts +311 -0
  64. package/src/index.ts +65 -19
  65. package/src/specs/RnIap.nitro.ts +13 -2
  66. package/src/types/amazon-devices-kepler/index.d.ts +14 -0
  67. package/src/types.ts +17 -3
  68. package/src/utils/error.ts +2 -2
  69. package/src/utils/type-bridge.ts +4 -1
  70. package/src/vega-adapter.ts +1503 -0
  71. package/src/vega.kepler.ts +21 -0
  72. package/src/vega.ts +10 -0
  73. package/android/src/test/java/com/margelo/nitro/iap/ListenerThreadSafetyTest.kt +0 -154
  74. package/android/src/test/java/com/margelo/nitro/iap/OpenIapExceptionTest.kt +0 -93
  75. package/android/src/test/java/com/margelo/nitro/iap/ProductQueryHelpersTest.kt +0 -140
  76. package/app.plugin.js +0 -1
  77. package/lib/typescript/plugin/src/withIAP.d.ts +0 -48
  78. package/lib/typescript/plugin/src/withIAP.d.ts.map +0 -1
  79. package/plugin/build/withIAP.d.ts +0 -47
  80. package/plugin/build/withIAP.js +0 -314
  81. package/plugin/src/withIAP.ts +0 -500
  82. package/plugin/tsconfig.json +0 -18
  83. package/plugin/tsconfig.tsbuildinfo +0 -1
@@ -1,314 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = exports.withIosAlternativeBilling = exports.modifyProjectBuildGradle = void 0;
4
- const config_plugins_1 = require("expo/config-plugins");
5
- const node_fs_1 = require("node:fs");
6
- const node_path_1 = require("node:path");
7
- const pkg = require('../../package.json');
8
- // Global flag to prevent duplicate logs
9
- let hasLoggedPluginExecution = false;
10
- const addLineToGradle = (content, anchor, lineToAdd, offset = 1) => {
11
- const lines = content.split('\n');
12
- const index = lines.findIndex((line) => line.match(anchor));
13
- if (index === -1) {
14
- console.warn(`Anchor "${anchor}" not found in build.gradle. Appending to end.`);
15
- lines.push(lineToAdd);
16
- }
17
- else {
18
- lines.splice(index + offset, 0, lineToAdd);
19
- }
20
- return lines.join('\n');
21
- };
22
- const modifyProjectBuildGradle = (gradle) => {
23
- // Keep backward-compatible behavior: add supportLibVersion inside ext { } if missing
24
- if (!gradle.includes('supportLibVersion')) {
25
- const lines = gradle.split('\n');
26
- const extIndex = lines.findIndex((line) => line.trim() === 'ext {');
27
- if (extIndex !== -1) {
28
- lines.splice(extIndex + 1, 0, 'supportLibVersion = "28.0.0"');
29
- return lines.join('\n');
30
- }
31
- }
32
- return gradle;
33
- };
34
- exports.modifyProjectBuildGradle = modifyProjectBuildGradle;
35
- const OPENIAP_COORD = 'io.github.hyochan.openiap:openiap-google';
36
- function loadOpenIapConfig() {
37
- const versionsPath = (0, node_path_1.resolve)(__dirname, '../../openiap-versions.json');
38
- try {
39
- const raw = (0, node_fs_1.readFileSync)(versionsPath, 'utf8');
40
- const parsed = JSON.parse(raw);
41
- const googleVersion = typeof parsed?.google === 'string' ? parsed.google.trim() : '';
42
- if (!googleVersion) {
43
- throw new Error('react-native-iap: "google" version missing or invalid in openiap-versions.json');
44
- }
45
- return { google: googleVersion };
46
- }
47
- catch (error) {
48
- throw new Error(`react-native-iap: Unable to load openiap-versions.json (${error instanceof Error ? error.message : error})`);
49
- }
50
- }
51
- let cachedOpenIapVersion = null;
52
- const getOpenIapVersion = () => {
53
- if (cachedOpenIapVersion) {
54
- return cachedOpenIapVersion;
55
- }
56
- cachedOpenIapVersion = loadOpenIapConfig().google;
57
- return cachedOpenIapVersion;
58
- };
59
- const modifyAppBuildGradle = (gradle) => {
60
- let modified = gradle;
61
- let openiapVersion;
62
- try {
63
- openiapVersion = getOpenIapVersion();
64
- }
65
- catch (error) {
66
- config_plugins_1.WarningAggregator.addWarningAndroid('react-native-iap', `react-native-iap: Failed to resolve OpenIAP version (${error instanceof Error ? error.message : error})`);
67
- return gradle;
68
- }
69
- // Replace legacy Billing/GMS instructions with OpenIAP Google library
70
- // Remove any old billingclient or play-services-base lines we may have added previously
71
- modified = modified
72
- .replace(/^[ \t]*(implementation|api)[ \t]+["']com\.android\.billingclient:billing-ktx:[^"']+["'][ \t]*$/gim, '')
73
- .replace(/^[ \t]*(implementation|api)[ \t]+["']com\.google\.android\.gms:play-services-base:[^"']+["'][ \t]*$/gim, '')
74
- .replace(/\n{3,}/g, '\n\n');
75
- const openiapDep = ` implementation "${OPENIAP_COORD}:${openiapVersion}"`;
76
- if (!modified.includes(OPENIAP_COORD)) {
77
- if (!/dependencies\s*{/.test(modified)) {
78
- modified += `\n\ndependencies {\n${openiapDep}\n}\n`;
79
- }
80
- else {
81
- modified = addLineToGradle(modified, /dependencies\s*{/, openiapDep);
82
- }
83
- if (!hasLoggedPluginExecution) {
84
- console.log(`🛠️ react-native-iap: Added OpenIAP (${openiapVersion}) to build.gradle`);
85
- }
86
- }
87
- return modified;
88
- };
89
- const withIapAndroid = (config, props) => {
90
- // Add OpenIAP dependency to app build.gradle
91
- config = (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
92
- config.modResults.contents = modifyAppBuildGradle(config.modResults.contents);
93
- return config;
94
- });
95
- config = (0, config_plugins_1.withAndroidManifest)(config, (config) => {
96
- const manifest = config.modResults;
97
- if (!manifest.manifest['uses-permission']) {
98
- manifest.manifest['uses-permission'] = [];
99
- }
100
- const permissions = manifest.manifest['uses-permission'];
101
- const billingPerm = { $: { 'android:name': 'com.android.vending.BILLING' } };
102
- const alreadyExists = permissions.some((p) => p.$['android:name'] === 'com.android.vending.BILLING');
103
- if (!alreadyExists) {
104
- permissions.push(billingPerm);
105
- if (!hasLoggedPluginExecution) {
106
- console.log('✅ Added com.android.vending.BILLING to AndroidManifest.xml');
107
- }
108
- }
109
- else {
110
- if (!hasLoggedPluginExecution) {
111
- console.log('ℹ️ com.android.vending.BILLING already exists in AndroidManifest.xml');
112
- }
113
- }
114
- // Add IAPKit API key as meta-data if provided
115
- if (props?.iapkitApiKey) {
116
- const application = manifest.manifest.application;
117
- const app = application?.[0];
118
- if (app) {
119
- if (!app['meta-data']) {
120
- app['meta-data'] = [];
121
- }
122
- const metaDataKey = 'dev.iapkit.API_KEY';
123
- const existingMetaData = app['meta-data'].find((m) => m.$?.['android:name'] === metaDataKey);
124
- if (!existingMetaData) {
125
- app['meta-data'].push({
126
- $: {
127
- 'android:name': metaDataKey,
128
- 'android:value': props.iapkitApiKey,
129
- },
130
- });
131
- if (!hasLoggedPluginExecution) {
132
- console.log('✅ Added IAPKit API key to AndroidManifest.xml');
133
- }
134
- }
135
- }
136
- }
137
- return config;
138
- });
139
- return config;
140
- };
141
- /** Add external purchase entitlements and Info.plist configuration */
142
- const withIosAlternativeBilling = (config, options) => {
143
- if (!options || !options.countries || options.countries.length === 0) {
144
- return config;
145
- }
146
- // Add entitlements
147
- config = (0, config_plugins_1.withEntitlementsPlist)(config, (config) => {
148
- // Always add basic external purchase entitlement when countries are specified
149
- config.modResults['com.apple.developer.storekit.external-purchase'] = true;
150
- if (!hasLoggedPluginExecution) {
151
- console.log('✅ Added com.apple.developer.storekit.external-purchase to entitlements');
152
- }
153
- // Add external purchase link entitlement if enabled
154
- if (options.enableExternalPurchaseLink) {
155
- config.modResults['com.apple.developer.storekit.external-purchase-link'] =
156
- true;
157
- if (!hasLoggedPluginExecution) {
158
- console.log('✅ Added com.apple.developer.storekit.external-purchase-link to entitlements');
159
- }
160
- }
161
- // Add streaming entitlement if enabled
162
- if (options.enableExternalPurchaseLinkStreaming) {
163
- config.modResults['com.apple.developer.storekit.external-purchase-link-streaming'] = true;
164
- if (!hasLoggedPluginExecution) {
165
- console.log('✅ Added com.apple.developer.storekit.external-purchase-link-streaming to entitlements');
166
- }
167
- }
168
- return config;
169
- });
170
- // Add Info.plist configuration
171
- config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
172
- const plist = config.modResults;
173
- // Helper function to normalize country codes to uppercase
174
- const normalize = (code) => code.trim().toUpperCase();
175
- // 1. SKExternalPurchase (Required)
176
- const normalizedCountries = options.countries?.map(normalize);
177
- plist.SKExternalPurchase = normalizedCountries;
178
- if (!hasLoggedPluginExecution) {
179
- console.log(`✅ Added SKExternalPurchase with countries: ${normalizedCountries?.join(', ')}`);
180
- }
181
- // 2. SKExternalPurchaseLink (Optional - iOS 15.4+)
182
- if (options.links && Object.keys(options.links).length > 0) {
183
- plist.SKExternalPurchaseLink = Object.fromEntries(Object.entries(options.links).map(([code, url]) => [
184
- normalize(code),
185
- url,
186
- ]));
187
- if (!hasLoggedPluginExecution) {
188
- console.log(`✅ Added SKExternalPurchaseLink for ${Object.keys(options.links).length} countries`);
189
- }
190
- }
191
- // 3. SKExternalPurchaseMultiLink (iOS 17.5+)
192
- if (options.multiLinks && Object.keys(options.multiLinks).length > 0) {
193
- plist.SKExternalPurchaseMultiLink = Object.fromEntries(Object.entries(options.multiLinks).map(([code, urls]) => [
194
- normalize(code),
195
- urls,
196
- ]));
197
- if (!hasLoggedPluginExecution) {
198
- console.log(`✅ Added SKExternalPurchaseMultiLink for ${Object.keys(options.multiLinks).length} countries`);
199
- }
200
- }
201
- // 4. SKExternalPurchaseCustomLinkRegions (iOS 18.1+)
202
- if (options.customLinkRegions && options.customLinkRegions.length > 0) {
203
- plist.SKExternalPurchaseCustomLinkRegions =
204
- options.customLinkRegions.map(normalize);
205
- if (!hasLoggedPluginExecution) {
206
- console.log(`✅ Added SKExternalPurchaseCustomLinkRegions: ${options.customLinkRegions
207
- .map(normalize)
208
- .join(', ')}`);
209
- }
210
- }
211
- // 5. SKExternalPurchaseLinkStreamingRegions (iOS 18.2+)
212
- if (options.streamingLinkRegions &&
213
- options.streamingLinkRegions.length > 0) {
214
- plist.SKExternalPurchaseLinkStreamingRegions =
215
- options.streamingLinkRegions.map(normalize);
216
- if (!hasLoggedPluginExecution) {
217
- console.log(`✅ Added SKExternalPurchaseLinkStreamingRegions: ${options.streamingLinkRegions
218
- .map(normalize)
219
- .join(', ')}`);
220
- }
221
- }
222
- return config;
223
- });
224
- return config;
225
- };
226
- exports.withIosAlternativeBilling = withIosAlternativeBilling;
227
- const withIapIosFollyWorkaround = (config, props) => {
228
- const newKey = props?.ios?.['with-folly-no-coroutines'];
229
- const oldKey = props?.ios?.['with-folly-no-couroutines'];
230
- if (oldKey && !hasLoggedPluginExecution) {
231
- // Temporary deprecation notice; remove when old key is dropped
232
- config_plugins_1.WarningAggregator.addWarningIOS('react-native-iap', "react-native-iap: 'ios.with-folly-no-couroutines' is deprecated; use 'ios.with-folly-no-coroutines'.");
233
- }
234
- const enabled = !!(newKey ?? oldKey);
235
- if (!enabled)
236
- return config;
237
- return (0, config_plugins_1.withPodfile)(config, (config) => {
238
- let contents = config.modResults.contents;
239
- // Idempotency: if any of the defines already exists, assume it's applied
240
- if (contents.includes('FOLLY_CFG_NO_COROUTINES') ||
241
- contents.includes('FOLLY_HAS_COROUTINES=0')) {
242
- return config;
243
- }
244
- const anchor = 'post_install do |installer|';
245
- const snippet = `
246
- # react-native-iap (expo): Disable Folly coroutines to avoid including non-vendored <folly/coro/*> headers
247
- installer.pods_project.targets.each do |target|
248
- target.build_configurations.each do |config|
249
- defs = (config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] || ['$(inherited)'])
250
- defs << 'FOLLY_NO_CONFIG=1' unless defs.any? { |d| d.to_s.include?('FOLLY_NO_CONFIG') }
251
- # Portability.h respects FOLLY_CFG_NO_COROUTINES to fully disable coroutine support
252
- defs << 'FOLLY_CFG_NO_COROUTINES=1' unless defs.any? { |d| d.to_s.include?('FOLLY_CFG_NO_COROUTINES') }
253
- defs << 'FOLLY_HAS_COROUTINES=0' unless defs.any? { |d| d.to_s.include?('FOLLY_HAS_COROUTINES') }
254
- config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = defs
255
- end
256
- end`;
257
- if (contents.includes(anchor)) {
258
- contents = contents.replace(anchor, `${anchor}\n${snippet}`);
259
- }
260
- else {
261
- // As a fallback, append a new post_install block
262
- contents += `
263
-
264
- ${anchor}
265
- ${snippet}
266
- end
267
- `;
268
- }
269
- config.modResults.contents = contents;
270
- return config;
271
- });
272
- };
273
- /** Add IAPKit API key to iOS Info.plist */
274
- const withIapkitApiKeyIOS = (config, apiKey) => {
275
- if (!apiKey) {
276
- return config;
277
- }
278
- return (0, config_plugins_1.withInfoPlist)(config, (config) => {
279
- const plist = config.modResults;
280
- const plistKey = 'IAPKitAPIKey';
281
- if (!plist[plistKey]) {
282
- plist[plistKey] = apiKey;
283
- if (!hasLoggedPluginExecution) {
284
- console.log('✅ Added IAPKit API key to Info.plist');
285
- }
286
- }
287
- return config;
288
- });
289
- };
290
- const withIAP = (config, props) => {
291
- try {
292
- let result = withIapAndroid(config, { iapkitApiKey: props?.iapkitApiKey });
293
- result = withIapIosFollyWorkaround(result, props);
294
- // Add iOS alternative billing configuration if provided
295
- if (props?.iosAlternativeBilling) {
296
- result = withIosAlternativeBilling(result, props.iosAlternativeBilling);
297
- }
298
- // Add IAPKit API key to iOS Info.plist if provided
299
- if (props?.iapkitApiKey) {
300
- result = withIapkitApiKeyIOS(result, props.iapkitApiKey);
301
- }
302
- // Set flag after first execution to prevent duplicate logs
303
- hasLoggedPluginExecution = true;
304
- return result;
305
- }
306
- catch (error) {
307
- config_plugins_1.WarningAggregator.addWarningAndroid('react-native-iap', `react-native-iap plugin encountered an error: ${error}`);
308
- console.error('react-native-iap plugin error:', error);
309
- return config;
310
- }
311
- };
312
- const _wrapped = (0, config_plugins_1.createRunOncePlugin)(withIAP, pkg.name, pkg.version);
313
- const pluginExport = ((config, props) => _wrapped(config, props));
314
- exports.default = pluginExport;