@umituz/react-native-subscription 2.37.13 → 2.37.14

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 (132) hide show
  1. package/package.json +1 -1
  2. package/src/domains/credits/application/PurchaseMetadataGenerator.ts +1 -1
  3. package/src/domains/credits/application/credit-strategies/CreditAllocationOrchestrator.ts +1 -1
  4. package/src/domains/credits/application/creditDocumentHelpers.ts +0 -14
  5. package/src/domains/credits/presentation/deduct-credit/index.ts +0 -1
  6. package/src/domains/credits/presentation/useCredits.ts +1 -6
  7. package/src/domains/credits/utils/creditValidation.ts +3 -3
  8. package/src/domains/paywall/components/PaywallFeatures.tsx +1 -1
  9. package/src/domains/paywall/hooks/usePaywallActions.ts +1 -1
  10. package/src/domains/revenuecat/core/errors/RevenueCatError.ts +1 -14
  11. package/src/domains/revenuecat/core/errors/RevenueCatErrorHandler.ts +1 -1
  12. package/src/domains/revenuecat/core/types/RevenueCatTypes.ts +3 -3
  13. package/src/domains/revenuecat/infrastructure/services/ConfigurationStateManager.ts +1 -1
  14. package/src/domains/revenuecat/infrastructure/services/RevenueCatInitializer.ts +0 -2
  15. package/src/domains/subscription/application/initializer/index.ts +1 -1
  16. package/src/domains/subscription/core/SubscriptionStatus.ts +4 -10
  17. package/src/domains/subscription/core/SubscriptionStatusHandlers.ts +1 -1
  18. package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +0 -2
  19. package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +1 -1
  20. package/src/domains/subscription/infrastructure/hooks/useRevenueCatTrialEligibility.ts +1 -2
  21. package/src/domains/subscription/infrastructure/hooks/useSubscriptionQueries.ts +0 -4
  22. package/src/domains/subscription/infrastructure/services/OfferingsFetcher.ts +1 -1
  23. package/src/domains/subscription/infrastructure/services/RestoreHandler.ts +1 -1
  24. package/src/domains/subscription/infrastructure/services/RevenueCatService.ts +1 -2
  25. package/src/domains/subscription/infrastructure/services/revenueCatServiceInstance.ts +0 -4
  26. package/src/domains/subscription/infrastructure/utils/renewal/index.ts +1 -1
  27. package/src/domains/subscription/presentation/components/details/CreditRow.tsx +1 -1
  28. package/src/domains/subscription/presentation/components/details/DetailRow.tsx +1 -1
  29. package/src/domains/subscription/presentation/components/feedback/FeedbackOption.tsx +0 -2
  30. package/src/domains/subscription/presentation/components/feedback/FeedbackTextInput.tsx +1 -1
  31. package/src/domains/subscription/presentation/featureGateRefs.ts +1 -1
  32. package/src/domains/subscription/presentation/screens/components/CreditsList.tsx +2 -2
  33. package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.tsx +0 -2
  34. package/src/domains/subscription/presentation/stores/index.ts +0 -5
  35. package/src/domains/subscription/presentation/stores/purchaseLoadingStore.ts +3 -7
  36. package/src/domains/subscription/presentation/useAuthAwarePurchase.ts +2 -8
  37. package/src/domains/subscription/presentation/useFeatureGate.ts +0 -2
  38. package/src/domains/subscription/presentation/usePaywallVisibility.ts +1 -1
  39. package/src/domains/subscription/utils/authGuards.ts +0 -23
  40. package/src/domains/subscription/utils/syncStatus.ts +1 -1
  41. package/src/domains/wallet/index.ts +0 -112
  42. package/src/domains/wallet/infrastructure/config/walletConfig.ts +1 -23
  43. package/src/domains/wallet/infrastructure/repositories/transaction/CollectionBuilder.ts +1 -1
  44. package/src/domains/wallet/infrastructure/repositories/transaction/index.ts +0 -9
  45. package/src/domains/wallet/presentation/components/BalanceCard.tsx +1 -1
  46. package/src/domains/wallet/presentation/components/TransactionItem.tsx +0 -2
  47. package/src/domains/wallet/presentation/components/TransactionList.tsx +3 -2
  48. package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +2 -2
  49. package/src/domains/wallet/presentation/hooks/useWallet.ts +2 -2
  50. package/src/shared/application/FeedbackService.ts +2 -2
  51. package/src/shared/infrastructure/SubscriptionEventBus.ts +1 -1
  52. package/src/shared/infrastructure/firestore/collectionUtils.ts +0 -7
  53. package/src/shared/infrastructure/firestore/resultUtils.ts +3 -39
  54. package/src/shared/presentation/layouts/ScreenLayout.tsx +1 -1
  55. package/src/shared/utils/numberUtils.core.ts +0 -27
  56. package/src/shared/utils/numberUtils.ts +1 -9
  57. package/src/shared/utils/validators.ts +0 -58
  58. package/src/domains/config/domain/entities/Plan.ts +0 -44
  59. package/src/domains/config/domain/index.ts +0 -2
  60. package/src/domains/config/domain/value-objects/Config.ts +0 -49
  61. package/src/domains/config/index.ts +0 -6
  62. package/src/domains/config/utils/planSelectors.ts +0 -56
  63. package/src/domains/paywall/components/FeatureItem.tsx +0 -50
  64. package/src/domains/paywall/components/FeatureList.tsx +0 -34
  65. package/src/domains/paywall/components/PaywallHeader.tsx +0 -112
  66. package/src/domains/paywall/hooks/usePaywallTranslations.ts +0 -78
  67. package/src/domains/paywall/hooks/useSubscriptionModal.ts +0 -45
  68. package/src/domains/paywall/index.ts +0 -13
  69. package/src/domains/revenuecat/core/constants/RevenueCatConstants.ts +0 -201
  70. package/src/domains/revenuecat/core/constants/index.ts +0 -5
  71. package/src/domains/revenuecat/core/customerInfoHelpers.ts +0 -21
  72. package/src/domains/revenuecat/core/index.ts +0 -7
  73. package/src/domains/revenuecat/index.ts +0 -7
  74. package/src/domains/revenuecat/infrastructure/index.ts +0 -5
  75. package/src/domains/revenuecat/infrastructure/services/index.ts +0 -7
  76. package/src/domains/subscription/infrastructure/hooks/customer-info/index.ts +0 -2
  77. package/src/domains/subscription/infrastructure/hooks/customer-info/types.ts +0 -9
  78. package/src/domains/subscription/infrastructure/hooks/customer-info/useCustomerInfo.ts +0 -52
  79. package/src/domains/subscription/infrastructure/hooks/useInitializeSubscription.ts +0 -30
  80. package/src/domains/subscription/infrastructure/hooks/usePaywallFlow.ts +0 -78
  81. package/src/domains/subscription/infrastructure/hooks/useRevenueCat.ts +0 -119
  82. package/src/domains/subscription/presentation/components/feedback/FeedbackConstants.ts +0 -6
  83. package/src/domains/subscription/presentation/screens/components/SubscriptionActions.tsx +0 -56
  84. package/src/domains/subscription/utils/dateFormatters.ts +0 -28
  85. package/src/domains/wallet/domain/entities/CreditCost.ts +0 -45
  86. package/src/domains/wallet/domain/entities/README.md +0 -41
  87. package/src/domains/wallet/domain/errors/README.md +0 -40
  88. package/src/domains/wallet/domain/errors/WalletError.ts +0 -17
  89. package/src/domains/wallet/domain/errors/WalletError.types.ts +0 -30
  90. package/src/domains/wallet/domain/errors/WalletErrorClasses.ts +0 -82
  91. package/src/domains/wallet/domain/errors/WalletErrorFactory.ts +0 -24
  92. package/src/domains/wallet/domain/errors/WalletErrorMessages.ts +0 -17
  93. package/src/domains/wallet/domain/types/credit-cost.types.ts +0 -86
  94. package/src/domains/wallet/domain/types/index.ts +0 -33
  95. package/src/domains/wallet/domain/types/wallet.types.ts +0 -50
  96. package/src/domains/wallet/infrastructure/services/product-metadata/CacheManager.ts +0 -30
  97. package/src/domains/wallet/infrastructure/services/product-metadata/FirebaseFetcher.ts +0 -17
  98. package/src/domains/wallet/infrastructure/services/product-metadata/ProductMetadataService.ts +0 -57
  99. package/src/domains/wallet/infrastructure/services/product-metadata/ServiceManager.ts +0 -29
  100. package/src/domains/wallet/infrastructure/services/product-metadata/index.ts +0 -7
  101. package/src/domains/wallet/presentation/hooks/index.ts +0 -8
  102. package/src/domains/wallet/presentation/hooks/useProductMetadata.ts +0 -72
  103. package/src/domains/wallet/utils/index.ts +0 -1
  104. package/src/shared/application/ActivationHandler.ts +0 -108
  105. package/src/shared/application/ports/ISubscriptionService.ts +0 -27
  106. package/src/shared/infrastructure/index.ts +0 -6
  107. package/src/shared/infrastructure/react-query/queryInvalidation.ts +0 -46
  108. package/src/shared/presentation/hooks/index.ts +0 -6
  109. package/src/shared/presentation/hooks/useAsyncState.ts +0 -72
  110. package/src/shared/presentation/hooks/useServiceCall.ts +0 -77
  111. package/src/shared/types/ReactTypes.ts +0 -80
  112. package/src/shared/utils/InsufficientCreditsError.ts +0 -32
  113. package/src/shared/utils/Logger.ts +0 -81
  114. package/src/shared/utils/SubscriptionConfig.ts +0 -15
  115. package/src/shared/utils/SubscriptionError.ts +0 -47
  116. package/src/shared/utils/appValidators.ts +0 -38
  117. package/src/shared/utils/arrayUtils.core.ts +0 -81
  118. package/src/shared/utils/arrayUtils.query.ts +0 -118
  119. package/src/shared/utils/arrayUtils.transforms.ts +0 -116
  120. package/src/shared/utils/arrayUtils.ts +0 -19
  121. package/src/shared/utils/errorUtils.ts +0 -32
  122. package/src/shared/utils/index.ts +0 -14
  123. package/src/shared/utils/numberUtils.aggregate.ts +0 -35
  124. package/src/shared/utils/numberUtils.format.ts +0 -42
  125. package/src/shared/utils/numberUtils.math.ts +0 -48
  126. package/src/shared/utils/queryKeyFactory.ts +0 -9
  127. package/src/shared/utils/stringUtils.case.ts +0 -64
  128. package/src/shared/utils/stringUtils.check.ts +0 -65
  129. package/src/shared/utils/stringUtils.format.ts +0 -84
  130. package/src/shared/utils/stringUtils.generate.ts +0 -47
  131. package/src/shared/utils/stringUtils.modify.ts +0 -67
  132. package/src/shared/utils/stringUtils.ts +0 -10
@@ -4,117 +4,6 @@
4
4
  * Public API for wallet functionality.
5
5
  */
6
6
 
7
- // Config
8
- export {
9
- configureWallet,
10
- getWalletConfig,
11
- resetWalletConfig,
12
- type WalletConfiguration,
13
- } from "./infrastructure/config/walletConfig";
14
-
15
- // Types
16
- export type {
17
- TransactionReason,
18
- CreditLog,
19
- TransactionRepositoryConfig,
20
- TransactionQueryOptions,
21
- TransactionResult,
22
- WalletConfig,
23
- ProductType,
24
- ProductMetadata,
25
- ProductMetadataConfig,
26
- CreditBalance,
27
- WalletTranslations,
28
- CreditCostConfig,
29
- AICreditCosts,
30
- CreditCostResult,
31
- } from "./domain/types";
32
-
33
- export {
34
- DEFAULT_AI_CREDIT_COSTS,
35
- getCreditCost,
36
- creditsToDollars,
37
- createCreditCostConfig,
38
- } from "./domain/types";
39
-
40
- // Errors
41
- export {
42
- WalletError,
43
- PaymentValidationError,
44
- PaymentProviderError,
45
- DuplicatePaymentError,
46
- UserValidationError,
47
- PackageValidationError,
48
- ReceiptValidationError,
49
- TransactionError,
50
- NetworkError,
51
- CreditLimitError,
52
- RefundError,
53
- handleWalletError,
54
- type WalletErrorCategory,
55
- } from "./domain/errors/WalletError";
56
-
57
- // Entities
58
- export {
59
- createCreditCostEntity,
60
- type CreditCostEntity,
61
- } from "./domain/entities/CreditCost";
62
-
63
- // Repositories
64
- export {
65
- TransactionRepository,
66
- createTransactionRepository,
67
- } from "./infrastructure/repositories/transaction";
68
-
69
- // Services
70
- export {
71
- ProductMetadataService,
72
- createProductMetadataService,
73
- configureProductMetadataService,
74
- getProductMetadataService,
75
- resetProductMetadataService,
76
- } from "./infrastructure/services/product-metadata";
77
-
78
- // Hooks
79
- export {
80
- useWallet,
81
- type UseWalletParams,
82
- type UseWalletResult,
83
- } from "./presentation/hooks/useWallet";
84
-
85
- export {
86
- useTransactionHistory,
87
- transactionQueryKeys,
88
- type UseTransactionHistoryParams,
89
- type UseTransactionHistoryResult,
90
- } from "./presentation/hooks/useTransactionHistory";
91
-
92
- export {
93
- useProductMetadata,
94
- productMetadataQueryKeys,
95
- type UseProductMetadataParams,
96
- type UseProductMetadataResult,
97
- } from "./presentation/hooks/useProductMetadata";
98
-
99
- // Components
100
- export {
101
- BalanceCard,
102
- type BalanceCardProps,
103
- type BalanceCardTranslations,
104
- } from "./presentation/components/BalanceCard";
105
-
106
- export {
107
- TransactionItem,
108
- type TransactionItemProps,
109
- type TransactionItemTranslations,
110
- } from "./presentation/components/TransactionItem";
111
-
112
- export {
113
- TransactionList,
114
- type TransactionListProps,
115
- type TransactionListTranslations,
116
- } from "./presentation/components/TransactionList";
117
-
118
7
  // Screens
119
8
  export {
120
9
  WalletScreen,
@@ -124,4 +13,3 @@ export type {
124
13
  WalletScreenProps,
125
14
  WalletScreenTranslations,
126
15
  } from "./presentation/screens/WalletScreen.types";
127
-
@@ -8,7 +8,7 @@
8
8
  import type { WalletScreenTranslations } from "../../presentation/screens/WalletScreen.types";
9
9
 
10
10
 
11
- export interface WalletConfiguration {
11
+ interface WalletConfiguration {
12
12
  translations: WalletScreenTranslations;
13
13
  transactionCollection: string;
14
14
  useUserSubcollection: boolean;
@@ -41,31 +41,9 @@ const DEFAULT_CONFIG: WalletConfiguration = {
41
41
 
42
42
  let walletConfig: WalletConfiguration = { ...DEFAULT_CONFIG };
43
43
 
44
- /**
45
- * Configure wallet settings globally
46
- * Call this once during app initialization
47
- */
48
- export function configureWallet(config: Partial<WalletConfiguration>): void {
49
- walletConfig = {
50
- ...DEFAULT_CONFIG,
51
- ...config,
52
- translations: {
53
- ...DEFAULT_CONFIG.translations,
54
- ...config.translations,
55
- },
56
- };
57
- }
58
-
59
44
  /**
60
45
  * Get current wallet configuration
61
46
  */
62
47
  export function getWalletConfig(): WalletConfiguration {
63
48
  return walletConfig;
64
49
  }
65
-
66
- /**
67
- * Reset wallet configuration to defaults
68
- */
69
- export function resetWalletConfig(): void {
70
- walletConfig = { ...DEFAULT_CONFIG };
71
- }
@@ -1,7 +1,7 @@
1
1
  import { buildCollectionRef, type CollectionConfig } from "../../../../../shared/infrastructure/firestore";
2
2
  import type { TransactionRepositoryConfig } from "../../../domain/types/transaction.types";
3
3
 
4
- export function getCollectionConfig(config: TransactionRepositoryConfig): CollectionConfig {
4
+ function getCollectionConfig(config: TransactionRepositoryConfig): CollectionConfig {
5
5
  return {
6
6
  collectionName: config.collectionName,
7
7
  useUserSubcollection: config.useUserSubcollection ?? false,
@@ -1,10 +1 @@
1
- import type { TransactionRepositoryConfig } from "../../../domain/types/transaction.types";
2
- import { TransactionRepository } from "./TransactionRepository";
3
-
4
1
  export { TransactionRepository } from "./TransactionRepository";
5
-
6
- export function createTransactionRepository(
7
- config: TransactionRepositoryConfig
8
- ): TransactionRepository {
9
- return new TransactionRepository(config);
10
- }
@@ -19,7 +19,7 @@ export interface BalanceCardTranslations {
19
19
  availableCredits: string;
20
20
  }
21
21
 
22
- export interface BalanceCardProps {
22
+ interface BalanceCardProps {
23
23
  balance: number;
24
24
  translations: BalanceCardTranslations;
25
25
  iconName?: string;
@@ -6,8 +6,6 @@ import { transactionItemStyles } from "./TransactionItem.styles";
6
6
  import type { TransactionItemProps } from "./TransactionItem.types";
7
7
  import { defaultDateFormatter, getReasonLabel, getChangePrefix } from "./transactionItemHelpers";
8
8
 
9
- export type { TransactionItemTranslations, TransactionItemProps } from "./TransactionItem.types";
10
-
11
9
  export const TransactionItem: React.FC<TransactionItemProps> = ({
12
10
  transaction,
13
11
  translations,
@@ -2,7 +2,8 @@ import React from "react";
2
2
  import { View, ScrollView } from "react-native";
3
3
  import { useAppDesignTokens, AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
4
4
  import type { CreditLog } from "../../domain/types/transaction.types";
5
- import { TransactionItem, type TransactionItemTranslations } from "./TransactionItem";
5
+ import { TransactionItem } from "./TransactionItem";
6
+ import type { TransactionItemTranslations } from "./TransactionItem.types";
6
7
  import { transactionListStyles } from "./TransactionList.styles";
7
8
  import { LoadingState, EmptyState } from "./TransactionListStates";
8
9
  import { DEFAULT_TRANSACTION_LIST_MAX_HEIGHT } from "./TransactionList.constants";
@@ -13,7 +14,7 @@ export interface TransactionListTranslations extends TransactionItemTranslations
13
14
  loading: string;
14
15
  }
15
16
 
16
- export interface TransactionListProps {
17
+ interface TransactionListProps {
17
18
  transactions: CreditLog[];
18
19
  loading: boolean;
19
20
  translations: TransactionListTranslations;
@@ -8,7 +8,7 @@ import type {
8
8
  } from "../../domain/types/transaction.types";
9
9
  import { TransactionRepository } from "../../infrastructure/repositories/transaction";
10
10
 
11
- export const transactionQueryKeys = {
11
+ const transactionQueryKeys = {
12
12
  all: ["transactions"] as const,
13
13
  user: (userId: string) => ["transactions", userId] as const,
14
14
  };
@@ -18,7 +18,7 @@ export interface UseTransactionHistoryParams {
18
18
  limit?: number;
19
19
  }
20
20
 
21
- export interface UseTransactionHistoryResult {
21
+ interface UseTransactionHistoryResult {
22
22
  transactions: CreditLog[];
23
23
  isLoading: boolean;
24
24
  error: Error | null;
@@ -13,12 +13,12 @@ import {
13
13
  } from "./useTransactionHistory";
14
14
  import type { CreditLog } from "../../domain/types/transaction.types";
15
15
 
16
- export interface UseWalletParams {
16
+ interface UseWalletParams {
17
17
  transactionConfig: UseTransactionHistoryParams["config"];
18
18
  transactionLimit?: number;
19
19
  }
20
20
 
21
- export interface UseWalletResult {
21
+ interface UseWalletResult {
22
22
  balance: number;
23
23
  balanceLoading: boolean;
24
24
  transactions: CreditLog[];
@@ -7,7 +7,7 @@
7
7
  import { collection, addDoc, doc } from "firebase/firestore";
8
8
  import { getFirestore } from "@umituz/react-native-firebase";
9
9
 
10
- export interface FeedbackData {
10
+ interface FeedbackData {
11
11
  userId: string | null;
12
12
  userEmail: string | null;
13
13
  type: string;
@@ -26,7 +26,7 @@ export interface FeedbackSubmitResult {
26
26
  * Submit feedback to Firestore
27
27
  * Stores under users/{userId}/feedback
28
28
  */
29
- export async function submitFeedback(
29
+ async function submitFeedback(
30
30
  data: FeedbackData
31
31
  ): Promise<FeedbackSubmitResult> {
32
32
  const db = getFirestore();
@@ -4,7 +4,7 @@ type EventCallback<T = unknown> = (data: T) => void;
4
4
  * Simple EventBus Implementation
5
5
  * Used to decouple services and provide an observer pattern for subscription events.
6
6
  */
7
- export class SubscriptionEventBus {
7
+ class SubscriptionEventBus {
8
8
  private static instance: SubscriptionEventBus;
9
9
  private listeners: Record<string, EventCallback<any>[]> = {};
10
10
 
@@ -57,10 +57,3 @@ export function requireFirestore(): Firestore {
57
57
  }
58
58
  return db;
59
59
  }
60
-
61
- /**
62
- * Safe check for Firestore availability
63
- */
64
- export function isFirestoreAvailable(): boolean {
65
- return getFirestore() !== null;
66
- }
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import type { Result } from "../../utils/Result";
7
- import { failure, success } from "../../utils/Result";
7
+ import { failure } from "../../utils/Result";
8
8
 
9
- export interface ApiError {
9
+ interface ApiError {
10
10
  message: string;
11
11
  code: string;
12
12
  }
@@ -14,20 +14,13 @@ export interface ApiError {
14
14
  /**
15
15
  * Create a standard error result
16
16
  */
17
- export function createErrorResult(
17
+ function createErrorResult(
18
18
  message: string,
19
19
  code: string = "UNKNOWN_ERROR"
20
20
  ): Result<never, ApiError> {
21
21
  return failure({ message, code });
22
22
  }
23
23
 
24
- /**
25
- * Create a database unavailable error result
26
- */
27
- export function createDbUnavailableResult<T>(): Result<T, ApiError> {
28
- return createErrorResult("Database not available", "DB_NOT_AVAILABLE");
29
- }
30
-
31
24
  /**
32
25
  * Map Error to ApiError result
33
26
  */
@@ -37,32 +30,3 @@ export function mapErrorToResult<T>(error: unknown): Result<T, ApiError> {
37
30
  return createErrorResult(message, code);
38
31
  }
39
32
 
40
- /**
41
- * Execute async function and return Result
42
- */
43
- export async function executeAsResult<T>(
44
- fn: () => Promise<T>
45
- ): Promise<Result<T, ApiError>> {
46
- try {
47
- const data = await fn();
48
- return success(data);
49
- } catch (error) {
50
- return mapErrorToResult<T>(error);
51
- }
52
- }
53
-
54
- /**
55
- * Validate database availability before executing
56
- */
57
- export async function withDbCheck<T>(
58
- fn: (db: any) => Promise<T>
59
- ): Promise<Result<T, ApiError>> {
60
- const { requireFirestore } = require("./collectionUtils");
61
-
62
- try {
63
- const db = requireFirestore();
64
- return await executeAsResult(() => fn(db));
65
- } catch (error) {
66
- return mapErrorToResult<T>(error);
67
- }
68
- }
@@ -7,7 +7,7 @@ import { StyleSheet, View, ScrollView, type ViewStyle, type ColorValue } from "r
7
7
  import { useSafeAreaInsets, type Edge } from "react-native-safe-area-context";
8
8
  import { useAppDesignTokens } from "@umituz/react-native-design-system";
9
9
 
10
- export interface ScreenLayoutProps {
10
+ interface ScreenLayoutProps {
11
11
  children: React.ReactNode;
12
12
  scrollable?: boolean;
13
13
  edges?: Edge[];
@@ -1,30 +1,3 @@
1
- export function clamp(value: number, min: number, max: number): number {
2
- return Math.min(Math.max(value, min), max);
3
- }
4
-
5
- export function roundTo(value: number, decimals: number = 2): number {
6
- const multiplier = Math.pow(10, decimals);
7
- return Math.round(value * multiplier) / multiplier;
8
- }
9
-
10
- export function calculatePercentage(value: number, total: number): number {
11
- if (total === 0) return 0;
12
- return (value / total) * 100;
13
- }
14
-
15
- export function calculatePercentageClamped(value: number, total: number): number {
16
- return clamp(calculatePercentage(value, total), 0, 100);
17
- }
18
-
19
- export function isApproximatelyEqual(a: number, b: number, epsilon: number = 0.0001): boolean {
20
- return Math.abs(a - b) < epsilon;
21
- }
22
-
23
- export function safeDivide(numerator: number, denominator: number): number {
24
- if (denominator === 0) return 0;
25
- return numerator / denominator;
26
- }
27
-
28
1
  export function calculateRemaining(current: number, cost: number): number {
29
2
  return Math.max(0, current - cost);
30
3
  }
@@ -1,9 +1 @@
1
- /**
2
- * Number Utilities
3
- * Re-exports all number utility modules
4
- */
5
-
6
- export * from "./numberUtils.aggregate";
7
- export * from "./numberUtils.core";
8
- export * from "./numberUtils.format";
9
- export * from "./numberUtils.math";
1
+ export { calculateRemaining } from "./numberUtils.core";
@@ -1,69 +1,11 @@
1
- export function isNonEmptyString(value: unknown): value is string {
2
- return typeof value === "string" && value.trim().length > 0;
3
- }
4
-
5
1
  export function isValidNumber(value: unknown): value is number {
6
2
  return typeof value === "number" && !isNaN(value) && isFinite(value);
7
3
  }
8
4
 
9
- export function isPositiveNumber(value: unknown): value is number {
10
- return isValidNumber(value) && value > 0;
11
- }
12
-
13
5
  export function isNonNegativeNumber(value: unknown): value is number {
14
6
  return isValidNumber(value) && value >= 0;
15
7
  }
16
8
 
17
- export function isInteger(value: unknown): value is number {
18
- return isValidNumber(value) && Number.isInteger(value);
19
- }
20
-
21
- export function isValidDate(value: unknown): boolean {
22
- if (value instanceof Date) {
23
- return !isNaN(value.getTime());
24
- }
25
- if (typeof value === "string" || typeof value === "number") {
26
- const d = new Date(value);
27
- return !isNaN(d.getTime());
28
- }
29
- return false;
30
- }
31
-
32
- export function isValidEmail(value: unknown): value is string {
33
- if (!isNonEmptyString(value)) return false;
34
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
35
- return emailRegex.test(value);
36
- }
37
-
38
- export function isValidUrl(value: unknown): value is string {
39
- if (!isNonEmptyString(value)) return false;
40
- try {
41
- new URL(value);
42
- return true;
43
- } catch {
44
- return false;
45
- }
46
- }
47
-
48
- export function isValueInRange(
49
- value: unknown,
50
- min: number,
51
- max: number,
52
- inclusive: boolean = true
53
- ): value is number {
54
- if (!isValidNumber(value)) return false;
55
- if (inclusive) return value >= min && value <= max;
56
- return value > min && value < max;
57
- }
58
-
59
- export function isNonEmptyArray<T>(value: unknown): value is [T, ...T[]] {
60
- return Array.isArray(value) && value.length > 0;
61
- }
62
-
63
- export function isPlainObject(value: unknown): value is Record<string, unknown> {
64
- return typeof value === "object" && value !== null && !Array.isArray(value);
65
- }
66
-
67
9
  export function isDefined<T>(value: T | null | undefined): value is T {
68
10
  return value !== null && value !== undefined;
69
11
  }
@@ -1,44 +0,0 @@
1
- /**
2
- * Plan Entity
3
- * Represents a subscription plan with credits and pricing
4
- */
5
-
6
- export type PlanType = "weekly" | "monthly" | "yearly" | "lifetime" | "custom";
7
-
8
- export interface Plan {
9
- readonly id: string;
10
- readonly type: PlanType;
11
- readonly credits: number;
12
- readonly price: number;
13
- readonly currency: string;
14
- readonly labelKey: string;
15
- readonly descriptionKey?: string;
16
- readonly isBestValue?: boolean;
17
- readonly isPopular?: boolean;
18
- }
19
-
20
- export interface PlanMetadata {
21
- readonly cost: number;
22
- readonly profit: number;
23
- readonly profitMargin: number;
24
- readonly pricePerCredit: number;
25
- }
26
-
27
- export const calculatePlanMetadata = (
28
- plan: Plan,
29
- costPerCredit: number,
30
- commissionRate: number = 0.30
31
- ): PlanMetadata => {
32
- const totalCost = plan.credits * costPerCredit;
33
- const netRevenue = plan.price * (1 - commissionRate);
34
- const profit = netRevenue - totalCost;
35
- const profitMargin = plan.price > 0 ? (profit / plan.price) * 100 : 0;
36
- const pricePerCredit = plan.credits > 0 ? plan.price / plan.credits : 0;
37
-
38
- return {
39
- cost: totalCost,
40
- profit,
41
- profitMargin,
42
- pricePerCredit,
43
- };
44
- };
@@ -1,2 +0,0 @@
1
- export * from "./entities/Plan";
2
- export * from "./value-objects/Config";
@@ -1,49 +0,0 @@
1
- /**
2
- * Subscription Configuration Value Object
3
- * Defines app-specific subscription plans and settings
4
- */
5
-
6
- import type { Plan } from "../entities/Plan";
7
-
8
- export interface ConfigTranslations {
9
- readonly title: string;
10
- readonly subtitle?: string;
11
- readonly creditsLabel: string;
12
- readonly creditsRemaining: string;
13
- readonly creditsTotal: string;
14
- readonly upgradeButton: string;
15
- readonly manageButton: string;
16
- readonly restoreButton: string;
17
- }
18
-
19
- export interface Config {
20
- readonly plans: readonly Plan[];
21
- readonly collectionName: string;
22
- readonly entitlementId: string;
23
- readonly translations: ConfigTranslations;
24
- readonly showCreditDetails?: boolean;
25
- readonly allowRestore?: boolean;
26
- readonly costPerCredit?: number;
27
- readonly commissionRate?: number;
28
- }
29
-
30
- export const DEFAULT_TRANSLATIONS: ConfigTranslations = {
31
- title: "subscription.title",
32
- subtitle: "subscription.subtitle",
33
- creditsLabel: "subscription.credits",
34
- creditsRemaining: "subscription.creditsRemaining",
35
- creditsTotal: "subscription.creditsTotal",
36
- upgradeButton: "subscription.upgrade",
37
- manageButton: "subscription.manage",
38
- restoreButton: "subscription.restore",
39
- };
40
-
41
- export const DEFAULT_CONFIG: Partial<Config> = {
42
- collectionName: "credits",
43
- entitlementId: "premium",
44
- translations: DEFAULT_TRANSLATIONS,
45
- showCreditDetails: true,
46
- allowRestore: true,
47
- costPerCredit: 0.04,
48
- commissionRate: 0.30,
49
- };
@@ -1,6 +0,0 @@
1
- /**
2
- * Subscription Config Domain
3
- * Configuration-driven subscription management
4
- */
5
-
6
- export * from "./domain";
@@ -1,56 +0,0 @@
1
- /**
2
- * Subscription Config Utilities
3
- * Helper functions for working with subscription configurations
4
- */
5
-
6
- import type { Plan, Config } from "../domain";
7
-
8
- export const getPlanByType = (
9
- config: Config,
10
- type: string
11
- ): Plan | undefined => {
12
- return config.plans.find((plan) => plan.type === type);
13
- };
14
-
15
- export const getPlanById = (
16
- config: Config,
17
- id: string
18
- ): Plan | undefined => {
19
- return config.plans.find((plan) => plan.id === id);
20
- };
21
-
22
- export const getBestValuePlan = (config: Config): Plan | undefined => {
23
- return config.plans.find((plan) => plan.isBestValue);
24
- };
25
-
26
- export const getPopularPlan = (config: Config): Plan | undefined => {
27
- return config.plans.find((plan) => plan.isPopular);
28
- };
29
-
30
- export const getCreditLimitForPlan = (
31
- config: Config,
32
- planId: string
33
- ): number => {
34
- const plan = getPlanById(config, planId);
35
- if (!plan) {
36
-
37
- return 0;
38
- }
39
- return plan.credits;
40
- };
41
-
42
- export const determinePlanFromCredits = (
43
- config: Config,
44
- currentCredits: number
45
- ): Plan | undefined => {
46
- const sortedPlans = [...config.plans].sort((a, b) => b.credits - a.credits);
47
-
48
- for (const plan of sortedPlans) {
49
- const threshold = plan.credits * 0.5;
50
- if (currentCredits >= threshold) {
51
- return plan;
52
- }
53
- }
54
-
55
- return sortedPlans[sortedPlans.length - 1];
56
- };