expo-iap 3.1.6 → 3.1.8
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 +92 -0
- package/build/helpers/subscription.d.ts.map +1 -1
- package/build/helpers/subscription.js +2 -1
- package/build/helpers/subscription.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -3
- package/build/index.js.map +1 -1
- package/build/useIAP.d.ts.map +1 -1
- package/build/useIAP.js +10 -9
- package/build/useIAP.js.map +1 -1
- package/build/utils/debug.d.ts +13 -0
- package/build/utils/debug.d.ts.map +1 -0
- package/build/utils/debug.js +53 -0
- package/build/utils/debug.js.map +1 -0
- package/bun.lockb +0 -0
- package/coverage/clover.xml +229 -207
- package/coverage/coverage-final.json +3 -2
- package/coverage/lcov-report/block-navigation.js +1 -1
- package/coverage/lcov-report/index.html +31 -31
- package/coverage/lcov-report/sorter.js +21 -7
- package/coverage/lcov-report/src/helpers/index.html +10 -10
- package/coverage/lcov-report/src/helpers/subscription.ts.html +10 -7
- package/coverage/lcov-report/src/index.html +14 -14
- package/coverage/lcov-report/src/index.ts.html +18 -12
- package/coverage/lcov-report/src/modules/android.ts.html +1 -1
- package/coverage/lcov-report/src/modules/index.html +1 -1
- package/coverage/lcov-report/src/modules/ios.ts.html +1 -1
- package/coverage/lcov-report/src/utils/debug.ts.html +283 -0
- package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
- package/coverage/lcov-report/src/utils/index.html +24 -9
- package/coverage/lcov.info +415 -362
- package/ios/ExpoIapModule.swift +1 -1
- package/openiap-versions.json +2 -2
- package/package.json +1 -1
- package/plugin/tsconfig.tsbuildinfo +1 -1
- package/src/helpers/subscription.ts +2 -1
- package/src/index.ts +6 -4
- package/src/useIAP.ts +12 -9
- package/src/utils/debug.ts +66 -0
package/ios/ExpoIapModule.swift
CHANGED
package/openiap-versions.json
CHANGED
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/expoConfig.augmentation.d.ts","./src/withIAP.ts","./src/withLocalOpenIAP.ts"],"version":"5.9.
|
|
1
|
+
{"root":["./src/expoConfig.augmentation.d.ts","./src/withIAP.ts","./src/withLocalOpenIAP.ts"],"version":"5.9.3"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Platform} from 'react-native';
|
|
2
2
|
import {getAvailablePurchases} from '../index';
|
|
3
3
|
import type {ActiveSubscription} from '../types';
|
|
4
|
+
import {ExpoIapConsole} from '../utils/debug';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Get all active subscriptions with detailed information
|
|
@@ -119,7 +120,7 @@ export const getActiveSubscriptions = async (
|
|
|
119
120
|
|
|
120
121
|
return activeSubscriptions;
|
|
121
122
|
} catch (error) {
|
|
122
|
-
|
|
123
|
+
ExpoIapConsole.error('Error getting active subscriptions:', error);
|
|
123
124
|
return [];
|
|
124
125
|
}
|
|
125
126
|
};
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
validateReceiptAndroid,
|
|
16
16
|
deepLinkToSubscriptionsAndroid,
|
|
17
17
|
} from './modules/android';
|
|
18
|
+
import {ExpoIapConsole} from './utils/debug';
|
|
18
19
|
|
|
19
20
|
// Types
|
|
20
21
|
import type {
|
|
@@ -90,8 +91,8 @@ export type ProductTypeInput = ProductQueryType | 'inapp';
|
|
|
90
91
|
|
|
91
92
|
const normalizeProductType = (type?: ProductTypeInput) => {
|
|
92
93
|
if (type === 'inapp') {
|
|
93
|
-
|
|
94
|
-
"
|
|
94
|
+
ExpoIapConsole.warn(
|
|
95
|
+
"'inapp' product type is deprecated and will be removed in v3.1.0. Use 'in-app' instead.",
|
|
95
96
|
);
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -184,7 +185,7 @@ export const promotedProductListenerIOS = (
|
|
|
184
185
|
listener: (product: Product) => void,
|
|
185
186
|
) => {
|
|
186
187
|
if (Platform.OS !== 'ios') {
|
|
187
|
-
|
|
188
|
+
ExpoIapConsole.warn(
|
|
188
189
|
'promotedProductListenerIOS: This listener is only available on iOS',
|
|
189
190
|
);
|
|
190
191
|
return {remove: () => {}};
|
|
@@ -206,7 +207,7 @@ export const endConnection: MutationField<'endConnection'> = async () =>
|
|
|
206
207
|
* @param request.type - Product query type: 'in-app', 'subs', or 'all'
|
|
207
208
|
*/
|
|
208
209
|
export const fetchProducts: QueryField<'fetchProducts'> = async (request) => {
|
|
209
|
-
|
|
210
|
+
ExpoIapConsole.debug('fetchProducts called with:', request);
|
|
210
211
|
const {skus, type} = request ?? {};
|
|
211
212
|
|
|
212
213
|
if (!Array.isArray(skus) || skus.length === 0) {
|
|
@@ -629,3 +630,4 @@ export type {
|
|
|
629
630
|
PurchaseError as ExpoPurchaseError,
|
|
630
631
|
PurchaseErrorProps,
|
|
631
632
|
} from './utils/errorMapping';
|
|
633
|
+
export {ExpoIapConsole} from './utils/debug';
|
package/src/useIAP.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type ActiveSubscription,
|
|
21
21
|
type ProductTypeInput,
|
|
22
22
|
} from './index';
|
|
23
|
+
import {ExpoIapConsole} from './utils/debug';
|
|
23
24
|
import {
|
|
24
25
|
getPromotedProductIOS,
|
|
25
26
|
requestPurchaseOnPromotedProductIOS,
|
|
@@ -194,7 +195,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
194
195
|
const result = await fetchProducts(request);
|
|
195
196
|
const items = (result ?? []) as (Product | ProductSubscription)[];
|
|
196
197
|
|
|
197
|
-
|
|
198
|
+
ExpoIapConsole.debug('Fetched products:', items);
|
|
198
199
|
|
|
199
200
|
if (queryType === 'subs') {
|
|
200
201
|
const subscriptionsResult = items as ProductSubscription[];
|
|
@@ -267,7 +268,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
267
268
|
);
|
|
268
269
|
}
|
|
269
270
|
} catch (error) {
|
|
270
|
-
|
|
271
|
+
ExpoIapConsole.error('Error fetching products:', error);
|
|
271
272
|
}
|
|
272
273
|
},
|
|
273
274
|
[canonicalProductType, mergeWithDuplicateCheck, normalizeProductQueryType],
|
|
@@ -281,7 +282,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
281
282
|
});
|
|
282
283
|
setAvailablePurchases(result);
|
|
283
284
|
} catch (error) {
|
|
284
|
-
|
|
285
|
+
ExpoIapConsole.error('Error fetching available purchases:', error);
|
|
285
286
|
}
|
|
286
287
|
}, []);
|
|
287
288
|
|
|
@@ -291,7 +292,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
291
292
|
const result = await getActiveSubscriptions(subscriptionIds);
|
|
292
293
|
setActiveSubscriptions(result);
|
|
293
294
|
} catch (error) {
|
|
294
|
-
|
|
295
|
+
ExpoIapConsole.error('Error getting active subscriptions:', error);
|
|
295
296
|
// Preserve existing state on error
|
|
296
297
|
}
|
|
297
298
|
},
|
|
@@ -303,7 +304,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
303
304
|
try {
|
|
304
305
|
return await hasActiveSubscriptions(subscriptionIds);
|
|
305
306
|
} catch (error) {
|
|
306
|
-
|
|
307
|
+
ExpoIapConsole.error('Error checking active subscriptions:', error);
|
|
307
308
|
return false;
|
|
308
309
|
}
|
|
309
310
|
},
|
|
@@ -341,7 +342,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
341
342
|
await getAvailablePurchasesInternal();
|
|
342
343
|
}
|
|
343
344
|
} catch (error) {
|
|
344
|
-
|
|
345
|
+
ExpoIapConsole.warn('Failed to refresh subscription status:', error);
|
|
345
346
|
}
|
|
346
347
|
},
|
|
347
348
|
[fetchProductsInternal, getAvailablePurchasesInternal],
|
|
@@ -363,7 +364,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
363
364
|
});
|
|
364
365
|
setAvailablePurchases(purchases);
|
|
365
366
|
} catch (error) {
|
|
366
|
-
|
|
367
|
+
ExpoIapConsole.warn('Failed to restore purchases:', error);
|
|
367
368
|
}
|
|
368
369
|
}, []);
|
|
369
370
|
|
|
@@ -395,7 +396,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
395
396
|
}
|
|
396
397
|
const friendly = getUserFriendlyErrorMessage(error);
|
|
397
398
|
if (!isUserCancelledError(error) && !isRecoverableError(error)) {
|
|
398
|
-
|
|
399
|
+
ExpoIapConsole.warn('[useIAP] Purchase error:', friendly);
|
|
399
400
|
}
|
|
400
401
|
|
|
401
402
|
if (optionsRef.current?.onPurchaseError) {
|
|
@@ -422,7 +423,9 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
422
423
|
setConnected(result);
|
|
423
424
|
if (!result) {
|
|
424
425
|
// If connection failed, clean up listeners
|
|
425
|
-
|
|
426
|
+
ExpoIapConsole.warn(
|
|
427
|
+
'[useIAP] Connection failed, cleaning up listeners...',
|
|
428
|
+
);
|
|
426
429
|
subscriptionsRef.current.purchaseUpdate?.remove();
|
|
427
430
|
subscriptionsRef.current.promotedProductIOS?.remove();
|
|
428
431
|
subscriptionsRef.current.purchaseUpdate = undefined;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug logger for Expo IAP
|
|
3
|
+
* Only logs when explicitly enabled for library development
|
|
4
|
+
* Silent for all library users (even in their dev mode)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Check if we're in library development mode
|
|
8
|
+
// This will be false for library users, even in their dev environment
|
|
9
|
+
const isLibraryDevelopment = () => {
|
|
10
|
+
// Only show logs if explicitly enabled via environment variable
|
|
11
|
+
// Library developers can set: EXPO_IAP_DEV_MODE=true
|
|
12
|
+
|
|
13
|
+
// Handle both Node.js and React Native environments
|
|
14
|
+
if (
|
|
15
|
+
typeof process !== 'undefined' &&
|
|
16
|
+
process.env?.EXPO_IAP_DEV_MODE === 'true'
|
|
17
|
+
) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Check global object (works in both environments)
|
|
22
|
+
if (
|
|
23
|
+
typeof globalThis !== 'undefined' &&
|
|
24
|
+
(globalThis as any).EXPO_IAP_DEV_MODE === true
|
|
25
|
+
) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return false;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const createConsole = () => ({
|
|
33
|
+
log: (...args: any[]) => {
|
|
34
|
+
if (isLibraryDevelopment()) {
|
|
35
|
+
console.log('[Expo-IAP]', ...args);
|
|
36
|
+
}
|
|
37
|
+
// Silent for library users
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
debug: (...args: any[]) => {
|
|
41
|
+
if (isLibraryDevelopment()) {
|
|
42
|
+
console.debug('[Expo-IAP Debug]', ...args);
|
|
43
|
+
}
|
|
44
|
+
// Silent for library users
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
warn: (...args: any[]) => {
|
|
48
|
+
// Warnings are always shown
|
|
49
|
+
console.warn('[Expo-IAP]', ...args);
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
error: (...args: any[]) => {
|
|
53
|
+
// Errors are always shown
|
|
54
|
+
console.error('[Expo-IAP]', ...args);
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
info: (...args: any[]) => {
|
|
58
|
+
if (isLibraryDevelopment()) {
|
|
59
|
+
console.info('[Expo-IAP]', ...args);
|
|
60
|
+
}
|
|
61
|
+
// Silent for library users
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Export a singleton instance
|
|
66
|
+
export const ExpoIapConsole = createConsole();
|