@umituz/react-native-subscription 2.27.53 → 2.27.54

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.27.53",
3
+ "version": "2.27.54",
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",
@@ -16,7 +16,8 @@ export type PurchaseSource =
16
16
  | "upgrade_prompt"
17
17
  | "home_screen"
18
18
  | "feature_gate"
19
- | "credits_exhausted";
19
+ | "credits_exhausted"
20
+ | "renewal";
20
21
 
21
22
  export type PurchaseType = "initial" | "renewal" | "upgrade" | "downgrade";
22
23
 
@@ -8,7 +8,8 @@ export type PurchaseSource =
8
8
  | "upgrade_prompt"
9
9
  | "home_screen"
10
10
  | "feature_gate"
11
- | "credits_exhausted";
11
+ | "credits_exhausted"
12
+ | "renewal";
12
13
 
13
14
  export type PurchaseType = "initial" | "renewal" | "upgrade" | "downgrade";
14
15
 
@@ -42,9 +42,10 @@ export class CreditsRepository extends BaseRepository {
42
42
  const entity = CreditsMapper.toEntity(d);
43
43
  if (__DEV__) console.log("[CreditsRepository] Credits fetched:", { credits: entity.credits, limit: entity.creditLimit });
44
44
  return { success: true, data: entity };
45
- } catch (e: any) {
46
- if (__DEV__) console.error("[CreditsRepository] Fetch error:", e.message);
47
- return { success: false, error: { message: e.message, code: "FETCH_ERR" } };
45
+ } catch (e: unknown) {
46
+ const message = e instanceof Error ? e.message : String(e);
47
+ if (__DEV__) console.error("[CreditsRepository] Fetch error:", message);
48
+ return { success: false, error: { message, code: "FETCH_ERR" } };
48
49
  }
49
50
  }
50
51
 
@@ -80,8 +81,9 @@ export class CreditsRepository extends BaseRepository {
80
81
  success: true,
81
82
  data: CreditsMapper.toEntity({ ...res, purchasedAt: undefined, lastUpdatedAt: undefined })
82
83
  };
83
- } catch (e: any) {
84
- return { success: false, error: { message: e.message, code: "INIT_ERR" } };
84
+ } catch (e: unknown) {
85
+ const message = e instanceof Error ? e.message : String(e);
86
+ return { success: false, error: { message, code: "INIT_ERR" } };
85
87
  }
86
88
  }
87
89
 
@@ -99,9 +101,10 @@ export class CreditsRepository extends BaseRepository {
99
101
  return updated;
100
102
  });
101
103
  return { success: true, remainingCredits: remaining };
102
- } catch (e: any) {
103
- const code = e.message === "NO_CREDITS" || e.message === "CREDITS_EXHAUSTED" ? e.message : "DEDUCT_ERR";
104
- return { success: false, error: { message: e.message, code } };
104
+ } catch (e: unknown) {
105
+ const message = e instanceof Error ? e.message : String(e);
106
+ const code = message === "NO_CREDITS" || message === "CREDITS_EXHAUSTED" ? message : "DEDUCT_ERR";
107
+ return { success: false, error: { message, code } };
105
108
  }
106
109
  }
107
110
 
@@ -15,6 +15,7 @@ import { SubscriptionManager } from "../../revenuecat/infrastructure/managers/Su
15
15
  import { configureAuthProvider } from "../../presentation/hooks/useAuthAwarePurchase";
16
16
  import type { RevenueCatData } from "../../domain/types/RevenueCatData";
17
17
  import type { SubscriptionInitConfig, FirebaseAuthLike } from "./SubscriptionInitializerTypes";
18
+ import type { PurchaseSource } from "../../domain/entities/Credits";
18
19
 
19
20
  export type { FirebaseAuthLike, CreditPackageConfig, SubscriptionInitConfig } from "./SubscriptionInitializerTypes";
20
21
 
@@ -63,7 +64,6 @@ export const initializeSubscription = async (config: SubscriptionInitConfig): Pr
63
64
  apiKey, apiKeyIos, apiKeyAndroid, entitlementId, credits,
64
65
  getAnonymousUserId, getFirebaseAuth, showAuthModal,
65
66
  onCreditsUpdated, creditPackages,
66
- // Note: timeoutMs and authStateTimeoutMs are deprecated and ignored
67
67
  } = config;
68
68
 
69
69
  const key = Platform.OS === 'ios' ? (apiKeyIos || apiKey || '') : (apiKeyAndroid || apiKey || '');
@@ -71,11 +71,11 @@ export const initializeSubscription = async (config: SubscriptionInitConfig): Pr
71
71
 
72
72
  configureCreditsRepository({ ...credits, creditPackageAmounts: creditPackages?.amounts });
73
73
 
74
- const onPurchase = async (userId: string, productId: string, customerInfo: CustomerInfo, source?: string) => {
74
+ const onPurchase = async (userId: string, productId: string, customerInfo: CustomerInfo, source?: PurchaseSource) => {
75
75
  if (__DEV__) console.log('[SubscriptionInitializer] onPurchase:', { userId, productId, source });
76
76
  try {
77
77
  const revenueCatData = extractRevenueCatData(customerInfo, entitlementId);
78
- await getCreditsRepository().initializeCredits(userId, `purchase_${productId}_${Date.now()}`, productId, source as any, revenueCatData);
78
+ await getCreditsRepository().initializeCredits(userId, `purchase_${productId}_${Date.now()}`, productId, source, revenueCatData);
79
79
  onCreditsUpdated?.(userId);
80
80
  } catch (error) {
81
81
  if (__DEV__) console.error('[SubscriptionInitializer] Credits init failed:', error);
@@ -87,7 +87,7 @@ export const initializeSubscription = async (config: SubscriptionInitConfig): Pr
87
87
  try {
88
88
  const revenueCatData = extractRevenueCatData(customerInfo, entitlementId);
89
89
  revenueCatData.expirationDate = newExpirationDate || revenueCatData.expirationDate;
90
- await getCreditsRepository().initializeCredits(userId, `renewal_${productId}_${Date.now()}`, productId, "renewal" as any, revenueCatData);
90
+ await getCreditsRepository().initializeCredits(userId, `renewal_${productId}_${Date.now()}`, productId, "renewal", revenueCatData);
91
91
  onCreditsUpdated?.(userId);
92
92
  } catch (error) {
93
93
  if (__DEV__) console.error('[SubscriptionInitializer] Renewal credits init failed:', error);
@@ -115,7 +115,7 @@ export const initializeSubscription = async (config: SubscriptionInitConfig): Pr
115
115
  } else {
116
116
  if (__DEV__) console.log('[SubscriptionInitializer] Canceled but not expired, preserving until:', expiresAt);
117
117
  const revenueCatData: RevenueCatData = { expirationDate: expiresAt, willRenew: false, isPremium: true, periodType };
118
- await getCreditsRepository().initializeCredits(userId, `status_sync_canceled_${Date.now()}`, productId, "settings" as any, revenueCatData);
118
+ await getCreditsRepository().initializeCredits(userId, `status_sync_canceled_${Date.now()}`, productId, "settings", revenueCatData);
119
119
  }
120
120
  onCreditsUpdated?.(userId);
121
121
  return;
@@ -123,7 +123,7 @@ export const initializeSubscription = async (config: SubscriptionInitConfig): Pr
123
123
 
124
124
  // Premium user - initialize credits with subscription data
125
125
  const revenueCatData: RevenueCatData = { expirationDate: expiresAt ?? null, willRenew: willRenew ?? false, isPremium, periodType };
126
- await getCreditsRepository().initializeCredits(userId, `status_sync_${Date.now()}`, productId, "settings" as any, revenueCatData);
126
+ await getCreditsRepository().initializeCredits(userId, `status_sync_${Date.now()}`, productId, "settings", revenueCatData);
127
127
  if (__DEV__) console.log('[SubscriptionInitializer] Premium status synced to Firestore');
128
128
  onCreditsUpdated?.(userId);
129
129
  } catch (error) {
@@ -25,14 +25,4 @@ export interface SubscriptionInitConfig {
25
25
  showAuthModal: () => void;
26
26
  onCreditsUpdated?: (userId: string) => void;
27
27
  creditPackages?: CreditPackageConfig;
28
- /**
29
- * @deprecated No longer used. Initialization is now non-blocking.
30
- * RevenueCat best practice: Use listener pattern instead of timeouts.
31
- */
32
- timeoutMs?: number;
33
- /**
34
- * @deprecated No longer used. Auth state is read synchronously.
35
- * Auth state changes are handled reactively via onAuthStateChanged listener.
36
- */
37
- authStateTimeoutMs?: number;
38
28
  }
@@ -1,4 +1,5 @@
1
1
  import type { CustomerInfo } from "react-native-purchases";
2
+ import type { PurchaseSource } from "../../../domain/entities/Credits";
2
3
 
3
4
  export interface RevenueCatConfig {
4
5
  apiKey?: string;
@@ -16,7 +17,7 @@ export interface RevenueCatConfig {
16
17
  userId: string,
17
18
  productId: string,
18
19
  customerInfo: CustomerInfo,
19
- source?: string
20
+ source?: PurchaseSource
20
21
  ) => Promise<void> | void;
21
22
  onRestoreCompleted?: (
22
23
  userId: string,
@@ -1,4 +1,4 @@
1
- import Purchases, { LOG_LEVEL } from "react-native-purchases";
1
+ import Purchases, { LOG_LEVEL, type CustomerInfo, type PurchasesOfferings } from "react-native-purchases";
2
2
  import type { InitializeResult } from "../../application/ports/IRevenueCatService";
3
3
  import type { RevenueCatConfig } from "../../domain/value-objects/RevenueCatConfig";
4
4
  import { resolveApiKey } from "../utils/ApiKeyResolver";
@@ -32,7 +32,7 @@ function configureLogHandler(): void {
32
32
  }
33
33
  }
34
34
 
35
- function buildSuccessResult(deps: InitializerDeps, customerInfo: any, offerings: any): InitializeResult {
35
+ function buildSuccessResult(deps: InitializerDeps, customerInfo: CustomerInfo, offerings: PurchasesOfferings): InitializeResult {
36
36
  const hasPremium = !!customerInfo.entitlements.active[deps.config.entitlementIdentifier];
37
37
  return { success: true, offering: offerings.current, hasPremium };
38
38
  }
@@ -35,28 +35,6 @@ export class InitializationCache {
35
35
  return { shouldInit: true, existingPromise: null };
36
36
  }
37
37
 
38
- /**
39
- * @deprecated Use tryAcquireInitialization instead for atomic operations
40
- */
41
- shouldReinitialize(userId: string): boolean {
42
- if (!this.initPromise) {
43
- return true;
44
- }
45
-
46
- if (this.currentUserId !== userId) {
47
- return true;
48
- }
49
-
50
- return false;
51
- }
52
-
53
- /**
54
- * @deprecated Use tryAcquireInitialization instead for atomic operations
55
- */
56
- getExistingPromise(): Promise<boolean> | null {
57
- return this.initPromise;
58
- }
59
-
60
38
  setPromise(promise: Promise<boolean>, userId: string): void {
61
39
  this.initPromise = promise;
62
40
  this.promiseUserId = userId;
@@ -5,6 +5,7 @@
5
5
 
6
6
  import type { CustomerInfo } from "react-native-purchases";
7
7
  import type { RevenueCatConfig } from "../../domain/value-objects/RevenueCatConfig";
8
+ import type { PurchaseSource } from "../../../domain/entities/Credits";
8
9
  import { getPremiumEntitlement } from "../../domain/types/RevenueCatTypes";
9
10
 
10
11
  declare const __DEV__: boolean;
@@ -48,7 +49,7 @@ export async function notifyPurchaseCompleted(
48
49
  userId: string,
49
50
  productId: string,
50
51
  customerInfo: CustomerInfo,
51
- source?: string
52
+ source?: PurchaseSource
52
53
  ): Promise<void> {
53
54
  if (__DEV__) {
54
55
  console.log('[PremiumStatusSyncer] notifyPurchaseCompleted called:', {