@umituz/react-native-subscription 2.31.0 → 2.31.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.31.0",
3
+ "version": "2.31.2",
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",
@@ -7,7 +7,7 @@ import {
7
7
  getCreditsConfig,
8
8
  isCreditsRepositoryConfigured,
9
9
  } from "../infrastructure/CreditsRepositoryManager";
10
- import { calculateCreditPercentage, canAfford as canAffordCheck } from "../../../shared/utils/numberUtils";
10
+ import { calculateSafePercentage, canAffordAmount } from "../utils/creditValidation";
11
11
  import { isAuthenticated } from "../../subscription/utils/authGuards";
12
12
  import { creditsQueryKeys } from "./creditsQueryKeys";
13
13
  import type { UseCreditsResult, CreditsLoadStatus } from "./useCredits.types";
@@ -73,12 +73,12 @@ export const useCredits = (): UseCreditsResult => {
73
73
  const derivedValues = useMemo(() => {
74
74
  const has = (credits?.credits ?? 0) > 0;
75
75
  const limit = config?.creditLimit ?? 0;
76
- const percent = calculateCreditPercentage(credits?.credits, limit);
76
+ const percent = calculateSafePercentage(credits?.credits, limit);
77
77
  return { hasCredits: has, creditsPercent: percent };
78
78
  }, [credits, config?.creditLimit]);
79
79
 
80
80
  const canAfford = useCallback(
81
- (cost: number): boolean => canAffordCheck(credits?.credits, cost),
81
+ (cost: number): boolean => canAffordAmount(credits?.credits, cost),
82
82
  [credits]
83
83
  );
84
84
 
@@ -1,11 +1,11 @@
1
- import { isValidNumber, isNonNegative } from "../../../shared/utils/typeGuards";
1
+ import { isValidNumber, isNonNegativeNumber } from "../../../shared/utils/validators";
2
2
 
3
3
  export const isValidBalance = (balance: number | null | undefined): balance is number => {
4
- return isValidNumber(balance) && isNonNegative(balance);
4
+ return isValidNumber(balance) && isNonNegativeNumber(balance);
5
5
  };
6
6
 
7
7
  export const isValidCost = (cost: number): boolean => {
8
- return isValidNumber(cost) && isNonNegative(cost);
8
+ return isValidNumber(cost) && isNonNegativeNumber(cost);
9
9
  };
10
10
 
11
11
  export const isValidMaxCredits = (max: number): boolean => {
@@ -21,10 +21,10 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
21
21
 
22
22
  const handleLegalUrl = useCallback(async (url: string | undefined) => {
23
23
  if (!url) return;
24
- try {
25
- if (await Linking.canOpenURL(url)) await Linking.openURL(url);
24
+ try {
25
+ if (await Linking.canOpenURL(url)) await Linking.openURL(url);
26
26
  } catch (err) {
27
- console.error("[PaywallModal] Legal link error:", err);
27
+ // Silently fail - legal links are non-critical
28
28
  }
29
29
  }, []);
30
30
 
@@ -15,7 +15,7 @@ export class SubscriptionSyncService {
15
15
  await this.processor.processPurchase(userId, productId, customerInfo, source);
16
16
  subscriptionEventBus.emit(SUBSCRIPTION_EVENTS.PURCHASE_COMPLETED, { userId, productId });
17
17
  } catch (err) {
18
- console.error("[SubscriptionSyncService] purchase error:", err);
18
+ // Swallow error - event bus consumers handle failures
19
19
  }
20
20
  }
21
21
 
@@ -24,23 +24,23 @@ export class SubscriptionSyncService {
24
24
  await this.processor.processRenewal(userId, productId, newExpirationDate, customerInfo);
25
25
  subscriptionEventBus.emit(SUBSCRIPTION_EVENTS.RENEWAL_DETECTED, { userId, productId });
26
26
  } catch (err) {
27
- console.error("[SubscriptionSyncService] renewal error:", err);
27
+ // Swallow error - event bus consumers handle failures
28
28
  }
29
29
  }
30
30
 
31
31
  async handlePremiumStatusChanged(
32
- userId: string,
33
- isPremium: boolean,
32
+ userId: string,
33
+ isPremium: boolean,
34
34
  productId?: string,
35
- expiresAt?: string,
36
- willRenew?: boolean,
35
+ expiresAt?: string,
36
+ willRenew?: boolean,
37
37
  periodType?: PeriodType
38
38
  ) {
39
39
  try {
40
40
  await this.processor.processStatusChange(userId, isPremium, productId, expiresAt, willRenew, periodType);
41
41
  subscriptionEventBus.emit(SUBSCRIPTION_EVENTS.PREMIUM_STATUS_CHANGED, { userId, isPremium });
42
42
  } catch (err) {
43
- console.error("[SubscriptionSyncService] status change error:", err);
43
+ // Swallow error - event bus consumers handle failures
44
44
  }
45
45
  }
46
46
  }
@@ -75,11 +75,6 @@ export class CustomerInfoListenerManager {
75
75
  customerInfo
76
76
  );
77
77
  } catch (error) {
78
- console.error('[CustomerInfoListener] Renewal callback failed', {
79
- userId: this.currentUserId,
80
- productId: renewalResult.productId,
81
- error
82
- });
83
78
  // Swallow error to prevent listener crash
84
79
  }
85
80
  }
@@ -95,12 +90,6 @@ export class CustomerInfoListenerManager {
95
90
  customerInfo
96
91
  );
97
92
  } catch (error) {
98
- console.error('[CustomerInfoListener] Plan change callback failed', {
99
- userId: this.currentUserId,
100
- productId: renewalResult.productId,
101
- previousProductId: renewalResult.previousProductId,
102
- error
103
- });
104
93
  // Swallow error to prevent listener crash
105
94
  }
106
95
  }
@@ -113,10 +102,6 @@ export class CustomerInfoListenerManager {
113
102
  try {
114
103
  await syncPremiumStatus(config, this.currentUserId, customerInfo);
115
104
  } catch (error) {
116
- console.error('[CustomerInfoListener] Premium status sync failed', {
117
- userId: this.currentUserId,
118
- error
119
- });
120
105
  // Swallow error to prevent listener crash
121
106
  }
122
107
  }
@@ -36,12 +36,6 @@ export async function syncPremiumStatus(
36
36
  await config.onPremiumStatusChanged(userId, false, undefined, undefined, undefined, undefined);
37
37
  }
38
38
  } catch (error) {
39
- console.error('[PremiumStatusSyncer] Premium status change callback failed', {
40
- userId,
41
- isPremium: !!premiumEntitlement,
42
- productId: premiumEntitlement?.productIdentifier,
43
- error
44
- });
45
39
  // Silently fail callback notifications to prevent crashing the main flow
46
40
  }
47
41
  }
@@ -60,12 +54,6 @@ export async function notifyPurchaseCompleted(
60
54
  try {
61
55
  await config.onPurchaseCompleted(userId, productId, customerInfo, source);
62
56
  } catch (error) {
63
- console.error('[PremiumStatusSyncer] Purchase completed callback failed', {
64
- userId,
65
- productId,
66
- source,
67
- error
68
- });
69
57
  // Silently fail callback notifications to prevent crashing the main flow
70
58
  }
71
59
  }
@@ -83,11 +71,6 @@ export async function notifyRestoreCompleted(
83
71
  try {
84
72
  await config.onRestoreCompleted(userId, isPremium, customerInfo);
85
73
  } catch (error) {
86
- console.error('[PremiumStatusSyncer] Restore completed callback failed', {
87
- userId,
88
- isPremium,
89
- error
90
- });
91
74
  // Silently fail callback notifications to prevent crashing the main flow
92
75
  }
93
76
  }
@@ -1,4 +1,4 @@
1
- import { isDefined } from "../../../shared/utils/typeGuards";
1
+ import { isDefined } from "../../../shared/utils/validators";
2
2
 
3
3
  export const isAuthenticated = (userId: string | null | undefined): userId is string => {
4
4
  return isDefined(userId) && userId.length > 0;
@@ -1,4 +1,4 @@
1
- import { isDefined } from "../../../shared/utils/typeGuards";
1
+ import { isDefined } from "../../../shared/utils/validators";
2
2
  import type { UserCredits } from "../../credits/core/Credits";
3
3
 
4
4
  export interface SyncState {
@@ -1,5 +1,3 @@
1
- import { canAffordAmount, calculateSafePercentage } from "../../domains/credits/utils/creditValidation";
2
-
3
1
  export function clamp(value: number, min: number, max: number): number {
4
2
  return Math.min(Math.max(value, min), max);
5
3
  }
@@ -30,11 +28,3 @@ export function safeDivide(numerator: number, denominator: number): number {
30
28
  export function calculateRemaining(current: number, cost: number): number {
31
29
  return Math.max(0, current - cost);
32
30
  }
33
-
34
- export function canAfford(balance: number | null | undefined, cost: number): boolean {
35
- return canAffordAmount(balance, cost);
36
- }
37
-
38
- export function calculateCreditPercentage(current: number | null | undefined, max: number): number {
39
- return calculateSafePercentage(current, max);
40
- }
@@ -1 +0,0 @@
1
- export const EXPIRATION_WARNING_DAYS = 7;
@@ -1 +0,0 @@
1
- export const TRANSACTION_LIST_MAX_HEIGHT = 400;
@@ -1,70 +0,0 @@
1
- /**
2
- * Common Type Definitions
3
- * Shared types used across multiple domains
4
- */
5
-
6
- import type { Platform as SubscriptionPlatform } from "../../domains/subscription/core/SubscriptionConstants";
7
-
8
- /**
9
- * Purchase result from any purchase operation
10
- */
11
- export interface PurchaseResult {
12
- success: boolean;
13
- productId?: string;
14
- error?: Error;
15
- }
16
-
17
- /**
18
- * Transaction result for repository operations
19
- */
20
- export interface TransactionResult<T = unknown> {
21
- success: boolean;
22
- data?: T;
23
- error?: Error;
24
- }
25
-
26
- /**
27
- * Subscription status information
28
- */
29
- export interface SubscriptionStatusInfo {
30
- isActive: boolean;
31
- isExpired: boolean;
32
- isTrial: boolean;
33
- willRenew: boolean;
34
- expirationDate?: Date;
35
- productId?: string;
36
- }
37
-
38
- /**
39
- * Credits information
40
- */
41
- export interface CreditsInfo {
42
- credits: number;
43
- creditLimit: number;
44
- isPremium: boolean;
45
- status: string;
46
- }
47
-
48
- /**
49
- * Transaction metadata for any transaction type
50
- */
51
- export interface TransactionMetadata {
52
- productId: string;
53
- amount: number;
54
- currency?: string;
55
- timestamp: Date;
56
- type: 'purchase' | 'renewal' | 'restore' | 'credit_purchase';
57
- }
58
-
59
- /**
60
- * Platform information
61
- */
62
- export type Platform = SubscriptionPlatform;
63
-
64
- /**
65
- * Purchase source tracking
66
- */
67
- export type PurchaseSource = 'settings' | 'paywall' | 'upgrade_prompt' | 'auto-execution' | 'manual';
68
-
69
- // Re-export from SubscriptionConstants to maintain compatibility
70
- export { PLATFORM, PURCHASE_SOURCE, type Platform as SubscriptionPlatformType, type PurchaseSource as PurchaseSourceType } from "../../domains/subscription/core/SubscriptionConstants";
@@ -1,15 +0,0 @@
1
- export const isDefined = <T>(value: T | null | undefined): value is T => {
2
- return value !== null && value !== undefined;
3
- };
4
-
5
- export const isPositive = (value: number): boolean => {
6
- return value > 0;
7
- };
8
-
9
- export const isNonNegative = (value: number): boolean => {
10
- return value >= 0;
11
- };
12
-
13
- export const isValidNumber = (value: number | null | undefined): value is number => {
14
- return isDefined(value) && !isNaN(value) && isFinite(value);
15
- };