@umituz/react-native-subscription 2.31.24 → 2.31.26
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 +1 -1
- package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +26 -2
- package/src/domains/subscription/infrastructure/hooks/useSubscriptionPackages.ts +28 -3
- package/src/domains/subscription/infrastructure/services/OfferingsFetcher.ts +30 -0
- package/src/domains/subscription/presentation/useSubscriptionStatus.ts +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.31.
|
|
3
|
+
"version": "2.31.26",
|
|
4
4
|
"description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -8,6 +8,8 @@ import type { IRevenueCatService } from "../../../../shared/application/ports/IR
|
|
|
8
8
|
import { getPremiumEntitlement } from "../../../revenuecat/core/types";
|
|
9
9
|
import { PurchaseStatusResolver, type PremiumStatus } from "./PurchaseStatusResolver";
|
|
10
10
|
|
|
11
|
+
declare const __DEV__: boolean;
|
|
12
|
+
|
|
11
13
|
export interface RestoreResultInfo {
|
|
12
14
|
success: boolean;
|
|
13
15
|
productId: string | null;
|
|
@@ -31,19 +33,41 @@ export class PackageHandler {
|
|
|
31
33
|
try {
|
|
32
34
|
const offering = await this.service.fetchOfferings();
|
|
33
35
|
|
|
36
|
+
if (__DEV__) {
|
|
37
|
+
console.log('[PackageHandler] fetchOfferings result:', {
|
|
38
|
+
hasOffering: !!offering,
|
|
39
|
+
offeringId: offering?.identifier,
|
|
40
|
+
packagesCount: offering?.availablePackages?.length,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
if (!offering) {
|
|
35
|
-
|
|
45
|
+
if (__DEV__) {
|
|
46
|
+
console.warn('[PackageHandler] No offering returned, returning empty array');
|
|
47
|
+
}
|
|
36
48
|
return [];
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
const packages = offering.availablePackages;
|
|
40
52
|
if (!packages || packages.length === 0) {
|
|
41
|
-
|
|
53
|
+
if (__DEV__) {
|
|
54
|
+
console.warn('[PackageHandler] Offering has no packages, returning empty array');
|
|
55
|
+
}
|
|
42
56
|
return [];
|
|
43
57
|
}
|
|
44
58
|
|
|
59
|
+
if (__DEV__) {
|
|
60
|
+
console.log('[PackageHandler] Returning packages:', {
|
|
61
|
+
count: packages.length,
|
|
62
|
+
packageIds: packages.map(p => p.product.identifier),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
45
66
|
return packages;
|
|
46
67
|
} catch (error) {
|
|
68
|
+
if (__DEV__) {
|
|
69
|
+
console.error('[PackageHandler] Error fetching packages:', error);
|
|
70
|
+
}
|
|
47
71
|
throw new Error(
|
|
48
72
|
`Failed to fetch subscription packages. ${
|
|
49
73
|
error instanceof Error ? error.message : "Unknown error"
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Auth info automatically read from @umituz/react-native-auth
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { useQuery } from "@umituz/react-native-design-system";
|
|
7
|
+
import { useQuery, useQueryClient } from "@umituz/react-native-design-system";
|
|
8
|
+
import { useEffect, useRef } from "react";
|
|
8
9
|
import {
|
|
9
10
|
useAuthStore,
|
|
10
11
|
selectUserId,
|
|
@@ -22,11 +23,12 @@ import {
|
|
|
22
23
|
export const useSubscriptionPackages = () => {
|
|
23
24
|
const userId = useAuthStore(selectUserId);
|
|
24
25
|
const isConfigured = SubscriptionManager.isConfigured();
|
|
26
|
+
const queryClient = useQueryClient();
|
|
27
|
+
const prevUserIdRef = useRef(userId);
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
const query = useQuery({
|
|
27
30
|
queryKey: [...SUBSCRIPTION_QUERY_KEYS.packages, userId ?? "anonymous"] as const,
|
|
28
31
|
queryFn: async () => {
|
|
29
|
-
// Initialize if needed (works for both authenticated and anonymous users)
|
|
30
32
|
if (userId) {
|
|
31
33
|
if (!SubscriptionManager.isInitializedForUser(userId)) {
|
|
32
34
|
await SubscriptionManager.initialize(userId);
|
|
@@ -46,4 +48,27 @@ export const useSubscriptionPackages = () => {
|
|
|
46
48
|
refetchOnWindowFocus: false,
|
|
47
49
|
refetchOnReconnect: true,
|
|
48
50
|
});
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const prevUserId = prevUserIdRef.current;
|
|
54
|
+
prevUserIdRef.current = userId;
|
|
55
|
+
|
|
56
|
+
if (prevUserId !== userId) {
|
|
57
|
+
if (prevUserId) {
|
|
58
|
+
queryClient.removeQueries({
|
|
59
|
+
queryKey: [...SUBSCRIPTION_QUERY_KEYS.packages, prevUserId],
|
|
60
|
+
});
|
|
61
|
+
} else {
|
|
62
|
+
queryClient.removeQueries({
|
|
63
|
+
queryKey: [...SUBSCRIPTION_QUERY_KEYS.packages, "anonymous"],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
queryClient.invalidateQueries({
|
|
68
|
+
queryKey: [...SUBSCRIPTION_QUERY_KEYS.packages, userId ?? "anonymous"],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}, [userId, queryClient]);
|
|
72
|
+
|
|
73
|
+
return query;
|
|
49
74
|
};
|
|
@@ -4,22 +4,52 @@ export interface OfferingsFetcherDeps {
|
|
|
4
4
|
isInitialized: () => boolean;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
declare const __DEV__: boolean;
|
|
8
|
+
|
|
7
9
|
export async function fetchOfferings(deps: OfferingsFetcherDeps): Promise<PurchasesOffering | null> {
|
|
8
10
|
if (!deps.isInitialized()) return null;
|
|
9
11
|
try {
|
|
10
12
|
const offerings = await Purchases.getOfferings();
|
|
11
13
|
|
|
14
|
+
if (__DEV__) {
|
|
15
|
+
console.log('[OfferingsFetcher] Offerings received:', {
|
|
16
|
+
hasCurrent: !!offerings.current,
|
|
17
|
+
currentId: offerings.current?.identifier,
|
|
18
|
+
allOfferingsCount: Object.keys(offerings.all).length,
|
|
19
|
+
allOfferingIds: Object.keys(offerings.all),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
if (offerings.current) {
|
|
24
|
+
if (__DEV__) {
|
|
25
|
+
console.log('[OfferingsFetcher] Using current offering:', {
|
|
26
|
+
id: offerings.current.identifier,
|
|
27
|
+
packagesCount: offerings.current.availablePackages.length,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
13
30
|
return offerings.current;
|
|
14
31
|
}
|
|
15
32
|
|
|
16
33
|
const allOfferings = Object.values(offerings.all);
|
|
17
34
|
if (allOfferings.length > 0) {
|
|
35
|
+
if (__DEV__) {
|
|
36
|
+
console.log('[OfferingsFetcher] No current offering, using first from all:', {
|
|
37
|
+
id: allOfferings[0].identifier,
|
|
38
|
+
packagesCount: allOfferings[0].availablePackages.length,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
18
41
|
return allOfferings[0];
|
|
19
42
|
}
|
|
20
43
|
|
|
44
|
+
if (__DEV__) {
|
|
45
|
+
console.warn('[OfferingsFetcher] No offerings available!');
|
|
46
|
+
}
|
|
47
|
+
|
|
21
48
|
return null;
|
|
22
49
|
} catch (error) {
|
|
50
|
+
if (__DEV__) {
|
|
51
|
+
console.error('[OfferingsFetcher] Error:', error);
|
|
52
|
+
}
|
|
23
53
|
throw new Error(`Failed to fetch offerings: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
24
54
|
}
|
|
25
55
|
}
|
|
@@ -15,8 +15,9 @@ export const subscriptionStatusQueryKeys = {
|
|
|
15
15
|
export const useSubscriptionStatus = (): SubscriptionStatusResult => {
|
|
16
16
|
const userId = useAuthStore(selectUserId);
|
|
17
17
|
const queryClient = useQueryClient();
|
|
18
|
+
const isConfigured = SubscriptionManager.isConfigured();
|
|
18
19
|
|
|
19
|
-
const queryEnabled = isAuthenticated(userId) &&
|
|
20
|
+
const queryEnabled = isAuthenticated(userId) && isConfigured;
|
|
20
21
|
|
|
21
22
|
const { data, status, error, refetch } = useQuery({
|
|
22
23
|
queryKey: subscriptionStatusQueryKeys.user(userId),
|
|
@@ -25,6 +26,10 @@ export const useSubscriptionStatus = (): SubscriptionStatusResult => {
|
|
|
25
26
|
return null;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
if (!SubscriptionManager.isInitializedForUser(userId)) {
|
|
30
|
+
await SubscriptionManager.initialize(userId);
|
|
31
|
+
}
|
|
32
|
+
|
|
28
33
|
try {
|
|
29
34
|
const result = await SubscriptionManager.checkPremiumStatus();
|
|
30
35
|
return result;
|