expo-iap 3.3.0-rc.3 → 3.3.0

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 (38) hide show
  1. package/CLAUDE.md +10 -4
  2. package/build/index.d.ts.map +1 -1
  3. package/build/index.js +24 -0
  4. package/build/index.js.map +1 -1
  5. package/coverage/clover.xml +26 -19
  6. package/coverage/coverage-final.json +5 -5
  7. package/coverage/lcov-report/block-navigation.js +1 -1
  8. package/coverage/lcov-report/index.html +19 -19
  9. package/coverage/lcov-report/sorter.js +21 -7
  10. package/coverage/lcov-report/src/index.html +19 -19
  11. package/coverage/lcov-report/src/index.ts.html +91 -10
  12. package/coverage/lcov-report/src/modules/android.ts.html +1 -1
  13. package/coverage/lcov-report/src/modules/index.html +1 -1
  14. package/coverage/lcov-report/src/modules/ios.ts.html +1 -1
  15. package/coverage/lcov-report/src/utils/debug.ts.html +1 -1
  16. package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
  17. package/coverage/lcov-report/src/utils/index.html +1 -1
  18. package/coverage/lcov.info +107 -93
  19. package/ios/ExpoIap.podspec +7 -5
  20. package/ios/ExpoIapHelper.swift +1 -1
  21. package/ios/ExpoIapModule.swift +22 -0
  22. package/openiap-versions.json +2 -2
  23. package/package.json +1 -1
  24. package/plugin/tsconfig.tsbuildinfo +1 -1
  25. package/scripts/update-types.mjs +44 -6
  26. package/src/index.ts +27 -0
  27. package/coverage/lcov-report/src/ExpoIap.types.ts.html +0 -1396
  28. package/coverage/lcov-report/src/helpers/index.html +0 -116
  29. package/coverage/lcov-report/src/helpers/subscription.ts.html +0 -499
  30. package/coverage/lcov-report/src/onside/ExpoOnsideMarketplaceAvailabilityModule.ts.html +0 -145
  31. package/coverage/lcov-report/src/onside/index.html +0 -131
  32. package/coverage/lcov-report/src/onside/index.ts.html +0 -253
  33. package/coverage/lcov-report/src/types/ExpoIapAndroid.types.ts.html +0 -502
  34. package/coverage/lcov-report/src/types/index.html +0 -116
  35. package/coverage/lcov-report/src/useIAP.ts.html +0 -1654
  36. package/coverage/lcov-report/src/utils/constants.ts.html +0 -127
  37. package/ios/expoiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  38. package/ios/expoiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
@@ -11,12 +11,14 @@ Pod::Spec.new do |s|
11
11
  s.license = package['license']
12
12
  s.author = package['author']
13
13
  s.homepage = package['homepage']
14
- # WARNING: DO NOT MODIFY platform versions from 13.4
15
- # Changing iOS/tvOS to 15.0 can cause expo prebuild to exclude the module in certain Expo SDKs (known bug)
14
+ # WARNING: DO NOT MODIFY iOS platform version from 13.4
15
+ # Changing iOS to 15.0 can cause expo prebuild to exclude the module in certain Expo SDKs (known bug)
16
16
  # See: https://github.com/hyochan/expo-iap/issues/168
17
- # Even though StoreKit 2 requires iOS/tvOS 15.0+, keep both at 13.4 for compatibility with affected Expo SDKs
18
- # The iOS/tvOS 15.0+ requirement is enforced at build time in source code via @available annotations
19
- s.platforms = { :ios => '13.4', :tvos => '13.4' }
17
+ # Even though StoreKit 2 requires iOS 15.0+, keep iOS at 13.4 for compatibility with affected Expo SDKs
18
+ # The iOS 15.0+ requirement is enforced at build time in source code via @available annotations
19
+ #
20
+ # NOTE: tvOS requires 16.0 because openiap dependency has minimum tvOS deployment target of 16.0
21
+ s.platforms = { :ios => '13.4', :tvos => '16.0' }
20
22
  s.swift_version = '5.9'
21
23
  s.source = { git: 'https://github.com/hyochan/expo-iap' }
22
24
  s.static_framework = true
@@ -4,7 +4,7 @@ import OpenIAP
4
4
 
5
5
  /// Exception wrapper for PurchaseError that preserves OpenIAP error codes
6
6
  /// This ensures consistent error format between try-catch and onPurchaseError callback
7
- class IapException: GenericException<(code: String, message: String, productId: String?)> {
7
+ final class IapException: GenericException<(code: String, message: String, productId: String?)>, @unchecked Sendable {
8
8
  override var code: String { param.code }
9
9
  override var reason: String { param.message }
10
10
 
@@ -291,6 +291,14 @@ public final class ExpoIapModule: Module {
291
291
  return nil
292
292
  }
293
293
 
294
+ AsyncFunction("requestPurchaseOnPromotedProductIOS") { () async throws -> Bool in
295
+ ExpoIapLog.payload("requestPurchaseOnPromotedProductIOS", payload: nil)
296
+ try await ExpoIapHelper.ensureConnection(isInitialized: self.isInitialized)
297
+ let success = try await OpenIapModule.shared.requestPurchaseOnPromotedProductIOS()
298
+ ExpoIapLog.result("requestPurchaseOnPromotedProductIOS", value: success)
299
+ return success
300
+ }
301
+
294
302
  AsyncFunction("getStorefront") { () async throws -> String in
295
303
  ExpoIapLog.payload("getStorefront", payload: nil)
296
304
  try await ExpoIapHelper.ensureConnection(isInitialized: self.isInitialized)
@@ -424,5 +432,19 @@ public final class ExpoIapModule: Module {
424
432
  ExpoIapLog.result("presentExternalPurchaseLinkIOS", value: sanitized)
425
433
  return sanitized
426
434
  }
435
+
436
+ // MARK: - App Transaction (iOS 16.0+)
437
+
438
+ AsyncFunction("getAppTransactionIOS") { () async throws -> [String: Any]? in
439
+ ExpoIapLog.payload("getAppTransactionIOS", payload: nil)
440
+ try await ExpoIapHelper.ensureConnection(isInitialized: self.isInitialized)
441
+ if let transaction = try await OpenIapModule.shared.getAppTransactionIOS() {
442
+ let sanitized = ExpoIapHelper.sanitizeDictionary(OpenIapSerialization.encode(transaction))
443
+ ExpoIapLog.result("getAppTransactionIOS", value: sanitized)
444
+ return sanitized
445
+ }
446
+ ExpoIapLog.result("getAppTransactionIOS", value: nil)
447
+ return nil
448
+ }
427
449
  }
428
450
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "apple": "1.3.2",
2
+ "apple": "1.3.5",
3
3
  "google": "1.3.14",
4
- "gql": "1.3.4"
4
+ "gql": "1.3.5"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-iap",
3
- "version": "3.3.0-rc.3",
3
+ "version": "3.3.0",
4
4
  "description": "In App Purchase module in Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1 +1 @@
1
- {"root":["./src/expoconfig.augmentation.d.ts","./src/withiap.ts","./src/withiosalternativebilling.ts","./src/withlocalopeniap.ts"],"version":"5.9.2"}
1
+ {"root":["./src/expoConfig.augmentation.d.ts","./src/withIAP.ts","./src/withIosAlternativeBilling.ts","./src/withLocalOpenIAP.ts"],"version":"5.9.3"}
@@ -45,17 +45,55 @@ function getReleaseUrl(tag) {
45
45
  return `https://github.com/hyodotdev/openiap/releases/download/${tag}/openiap-typescript.zip`;
46
46
  }
47
47
 
48
+ function resolveCandidateTags(tag) {
49
+ if (tag.startsWith('gql-')) {
50
+ return [tag];
51
+ }
52
+
53
+ // Prefer the new gql-<version> scheme but fall back to legacy bare tags
54
+ return [`gql-${tag}`, tag];
55
+ }
56
+
57
+ function downloadTypesArchive(zipPath, tags) {
58
+ let resolvedTag = null;
59
+ let lastError = null;
60
+
61
+ for (const [index, candidate] of tags.entries()) {
62
+ const releaseUrl = getReleaseUrl(candidate);
63
+ console.log(`Downloading OpenIAP types (tag: ${candidate}) from ${releaseUrl}`);
64
+
65
+ try {
66
+ execFileSync('curl', ['-L', '-o', zipPath, releaseUrl], {
67
+ stdio: 'inherit',
68
+ });
69
+ resolvedTag = candidate;
70
+ break;
71
+ } catch (error) {
72
+ lastError = error;
73
+ const hasFallback = index < tags.length - 1;
74
+ console.warn(
75
+ `Failed to download for tag ${candidate}; ${
76
+ hasFallback ? 'trying fallback' : 'no fallback available'
77
+ }.`,
78
+ );
79
+ }
80
+ }
81
+
82
+ if (!resolvedTag) {
83
+ throw lastError ?? new Error('Unable to download OpenIAP types archive.');
84
+ }
85
+
86
+ return resolvedTag;
87
+ }
88
+
48
89
  function main() {
49
90
  const {tag} = parseArgs();
50
- const releaseUrl = getReleaseUrl(tag);
91
+ const candidateTags = resolveCandidateTags(tag);
51
92
  const tempDir = mkdtempSync(join(tmpdir(), 'openiap-types-'));
52
93
  const zipPath = join(tempDir, 'openiap-typescript.zip');
53
94
 
54
95
  try {
55
- console.log(`Downloading OpenIAP types (tag: ${tag}) from ${releaseUrl}`);
56
- execFileSync('curl', ['-L', '-o', zipPath, releaseUrl], {
57
- stdio: 'inherit',
58
- });
96
+ const resolvedTag = downloadTypesArchive(zipPath, candidateTags);
59
97
 
60
98
  console.log('Extracting types.ts from archive');
61
99
  execFileSync('unzip', ['-o', zipPath, 'types.ts', '-d', tempDir], {
@@ -71,7 +109,7 @@ function main() {
71
109
 
72
110
  const destination = join(PROJECT_ROOT, 'src', 'types.ts');
73
111
  writeFileSync(destination, contents);
74
- console.log('Updated src/types.ts');
112
+ console.log(`Updated src/types.ts from tag ${resolvedTag}`);
75
113
  } finally {
76
114
  rmSync(tempDir, {recursive: true, force: true});
77
115
  }
package/src/index.ts CHANGED
@@ -808,6 +808,33 @@ export const verifyPurchaseWithProvider: MutationField<
808
808
  'verifyPurchaseWithProvider'
809
809
  > = async (options) => {
810
810
  if (Platform.OS === 'ios' || Platform.OS === 'android') {
811
+ // Auto-fill apiKey from config if not provided and provider is iapkit
812
+ if (
813
+ options.provider === 'iapkit' &&
814
+ options.iapkit &&
815
+ !options.iapkit.apiKey
816
+ ) {
817
+ try {
818
+ // Dynamically import expo-constants to avoid hard dependency
819
+ const {default: Constants} = await import('expo-constants');
820
+ const configApiKey = Constants.expoConfig?.extra?.iapkitApiKey;
821
+ if (configApiKey) {
822
+ options = {
823
+ ...options,
824
+ iapkit: {
825
+ ...options.iapkit,
826
+ apiKey: configApiKey,
827
+ },
828
+ };
829
+ }
830
+ } catch {
831
+ throw new Error(
832
+ 'expo-constants is required for auto-filling iapkitApiKey from config. ' +
833
+ 'Please install it: npx expo install expo-constants\n' +
834
+ 'Or provide apiKey directly in verifyPurchaseWithProvider options.',
835
+ );
836
+ }
837
+ }
811
838
  return ExpoIapModule.verifyPurchaseWithProvider(options);
812
839
  }
813
840