@umituz/react-native-subscription 2.14.96 โ†’ 2.14.98

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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +462 -0
  3. package/package.json +3 -3
  4. package/src/application/README.md +229 -0
  5. package/src/application/ports/README.md +103 -0
  6. package/src/domain/README.md +402 -0
  7. package/src/domain/constants/README.md +80 -0
  8. package/src/domain/entities/README.md +176 -0
  9. package/src/domain/errors/README.md +307 -0
  10. package/src/domain/value-objects/README.md +186 -0
  11. package/src/domains/config/README.md +390 -0
  12. package/src/domains/paywall/README.md +371 -0
  13. package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
  14. package/src/domains/paywall/components/README.md +185 -0
  15. package/src/domains/paywall/entities/README.md +199 -0
  16. package/src/domains/paywall/hooks/README.md +129 -0
  17. package/src/domains/wallet/README.md +292 -0
  18. package/src/domains/wallet/domain/README.md +108 -0
  19. package/src/domains/wallet/domain/entities/README.md +122 -0
  20. package/src/domains/wallet/domain/errors/README.md +157 -0
  21. package/src/domains/wallet/infrastructure/README.md +96 -0
  22. package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
  23. package/src/domains/wallet/presentation/components/README.md +231 -0
  24. package/src/domains/wallet/presentation/hooks/README.md +255 -0
  25. package/src/infrastructure/README.md +514 -0
  26. package/src/infrastructure/mappers/README.md +34 -0
  27. package/src/infrastructure/models/README.md +26 -0
  28. package/src/infrastructure/repositories/README.md +385 -0
  29. package/src/infrastructure/services/README.md +374 -0
  30. package/src/presentation/README.md +410 -0
  31. package/src/presentation/components/README.md +183 -0
  32. package/src/presentation/components/details/CreditRow.md +337 -0
  33. package/src/presentation/components/details/DetailRow.md +283 -0
  34. package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
  35. package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
  36. package/src/presentation/components/details/README.md +449 -0
  37. package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
  38. package/src/presentation/components/feedback/README.md +447 -0
  39. package/src/presentation/components/paywall/PaywallModal.md +444 -0
  40. package/src/presentation/components/paywall/README.md +190 -0
  41. package/src/presentation/components/sections/README.md +468 -0
  42. package/src/presentation/components/sections/SubscriptionSection.md +246 -0
  43. package/src/presentation/hooks/README.md +743 -0
  44. package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
  45. package/src/presentation/hooks/useAuthGate.md +403 -0
  46. package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
  47. package/src/presentation/hooks/useCreditChecker.md +407 -0
  48. package/src/presentation/hooks/useCredits.md +342 -0
  49. package/src/presentation/hooks/useCreditsGate.md +346 -0
  50. package/src/presentation/hooks/useDeductCredit.md +160 -0
  51. package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
  52. package/src/presentation/hooks/useFeatureGate.md +157 -0
  53. package/src/presentation/hooks/useInitializeCredits.md +458 -0
  54. package/src/presentation/hooks/usePaywall.md +334 -0
  55. package/src/presentation/hooks/usePaywallOperations.md +486 -0
  56. package/src/presentation/hooks/usePaywallVisibility.md +344 -0
  57. package/src/presentation/hooks/usePremium.md +230 -0
  58. package/src/presentation/hooks/usePremiumGate.md +423 -0
  59. package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
  60. package/src/presentation/hooks/useSubscription.md +450 -0
  61. package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
  62. package/src/presentation/hooks/useSubscriptionGate.md +168 -0
  63. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
  64. package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
  65. package/src/presentation/hooks/useUserTier.md +356 -0
  66. package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
  67. package/src/presentation/screens/README.md +194 -0
  68. package/src/presentation/types/README.md +38 -0
  69. package/src/presentation/utils/README.md +52 -0
  70. package/src/revenuecat/README.md +523 -0
  71. package/src/revenuecat/domain/README.md +147 -0
  72. package/src/revenuecat/domain/errors/README.md +197 -0
  73. package/src/revenuecat/infrastructure/config/README.md +40 -0
  74. package/src/revenuecat/infrastructure/managers/README.md +49 -0
  75. package/src/revenuecat/presentation/hooks/README.md +56 -0
  76. package/src/revenuecat/presentation/hooks/usePurchasePackage.ts +1 -1
  77. package/src/utils/README.md +529 -0
@@ -0,0 +1,160 @@
1
+ # useDeductCredit Hook
2
+
3
+ Hook for deducting credits from user balance with optimistic updates.
4
+
5
+ ## Import
6
+
7
+ ```typescript
8
+ import { useDeductCredit } from '@umituz/react-native-subscription';
9
+ ```
10
+
11
+ ## Signature
12
+
13
+ ```typescript
14
+ function useDeductCredit(params: {
15
+ userId: string | undefined;
16
+ onCreditsExhausted?: () => void;
17
+ }): {
18
+ deductCredit: (cost?: number) => Promise<boolean>;
19
+ deductCredits: (cost: number) => Promise<boolean>;
20
+ isDeducting: boolean;
21
+ }
22
+ ```
23
+
24
+ ## Parameters
25
+
26
+ | Parameter | Type | Default | Description |
27
+ |-----------|------|---------|-------------|
28
+ | `userId` | `string \| undefined` | **Required** | User ID for credit deduction |
29
+ | `onCreditsExhausted` | `() => void` | `undefined` | Callback when credits are exhausted |
30
+
31
+ ## Returns
32
+
33
+ | Property | Type | Description |
34
+ |----------|------|-------------|
35
+ | `deductCredit` | `(cost?: number) => Promise<boolean>` | Deduct credits (defaults to 1) |
36
+ | `deductCredits` | `(cost: number) => Promise<boolean>` | Deduct specific amount |
37
+ | `isDeducting` | `boolean` | Mutation is in progress |
38
+
39
+ ## Basic Usage
40
+
41
+ ```typescript
42
+ function CreditButton() {
43
+ const { user } = useAuth();
44
+ const { deductCredit, isDeducting } = useDeductCredit({
45
+ userId: user?.uid,
46
+ onCreditsExhausted: () => {
47
+ Alert.alert('Low Credits', 'Please purchase more credits');
48
+ },
49
+ });
50
+
51
+ const handleUseFeature = async () => {
52
+ const success = await deductCredit(1);
53
+ if (success) {
54
+ executePremiumFeature();
55
+ }
56
+ };
57
+
58
+ return (
59
+ <Button onPress={handleUseFeature} disabled={isDeducting}>
60
+ Use Feature (1 Credit)
61
+ </Button>
62
+ );
63
+ }
64
+ ```
65
+
66
+ ## Advanced Usage
67
+
68
+ ### With Custom Cost
69
+
70
+ ```typescript
71
+ function FeatureWithCost() {
72
+ const { deductCredit } = useDeductCredit({
73
+ userId: user?.uid,
74
+ });
75
+
76
+ const features = {
77
+ basic: { cost: 1, name: 'Basic Generation' },
78
+ advanced: { cost: 5, name: 'Advanced Generation' },
79
+ premium: { cost: 10, name: 'Premium Generation' },
80
+ };
81
+
82
+ const handleFeature = async (cost: number) => {
83
+ const success = await deductCredit(cost);
84
+ if (success) {
85
+ console.log('Feature used');
86
+ }
87
+ };
88
+
89
+ return (
90
+ <View>
91
+ {Object.entries(features).map(([key, { cost, name }]) => (
92
+ <Button
93
+ key={key}
94
+ onPress={() => handleFeature(cost)}
95
+ title={`${name} (${cost} credits)`}
96
+ />
97
+ ))}
98
+ </View>
99
+ );
100
+ }
101
+ ```
102
+
103
+ ### With Confirmation
104
+
105
+ ```typescript
106
+ function CreditDeductionWithConfirmation() {
107
+ const { deductCredit } = useDeductCredit({
108
+ userId: user?.uid,
109
+ });
110
+
111
+ const handleActionWithConfirmation = async (cost: number, action: string) => {
112
+ Alert.alert(
113
+ 'Confirm Action',
114
+ `This will cost ${cost} credit${cost > 1 ? 's' : ''}. Continue?`,
115
+ [
116
+ { text: 'Cancel', style: 'cancel' },
117
+ {
118
+ text: 'Confirm',
119
+ onPress: async () => {
120
+ const success = await deductCredit(cost);
121
+ if (success) {
122
+ await performAction(action);
123
+ }
124
+ },
125
+ },
126
+ ]
127
+ );
128
+ };
129
+
130
+ return (
131
+ <Button
132
+ onPress={() => handleActionWithConfirmation(5, 'export')}
133
+ title="Export Data (5 Credits)"
134
+ />
135
+ );
136
+ }
137
+ ```
138
+
139
+ ## Best Practices
140
+
141
+ 1. **Check balance first** - Show user if they have enough credits
142
+ 2. **Handle exhausted credits** - Provide purchase option
143
+ 3. **Show loading state** - Disable button during deduction
144
+ 4. **Optimistic updates** - UI updates automatically
145
+ 5. **Error handling** - Handle deduction failures gracefully
146
+ 6. **Confirm expensive actions** - Ask before large deductions
147
+ 7. **Clear messaging** - Tell users cost before deducting
148
+
149
+ ## Related Hooks
150
+
151
+ - **useCredits** - For accessing credits balance
152
+ - **useCreditsGate** - For gating features with credits
153
+ - **useInitializeCredits** - For initializing credits after purchase
154
+ - **useCreditChecker** - For checking credit availability
155
+
156
+ ## See Also
157
+
158
+ - [Credits README](../../../domains/wallet/README.md)
159
+ - [Credits Entity](../../../domains/wallet/domain/entities/Credits.md)
160
+ - [Credits Repository](../../../infrastructure/repositories/CreditsRepository.md)
@@ -0,0 +1,422 @@
1
+ # useDevTestCallbacks Hook
2
+
3
+ **Development-only** hook for testing subscription renewal and credit operations.
4
+
5
+ ## Import
6
+
7
+ ```typescript
8
+ import { useDevTestCallbacks } from '@umituz/react-native-subscription';
9
+ ```
10
+
11
+ ## Signature
12
+
13
+ ```typescript
14
+ function useDevTestCallbacks(): {
15
+ onTestRenewal: () => void;
16
+ onCheckCredits: () => void;
17
+ onTestDuplicate: () => void;
18
+ } | undefined
19
+ ```
20
+
21
+ ## Returns
22
+
23
+ Returns `undefined` in production. In development, returns:
24
+
25
+ | Property | Type | Description |
26
+ |----------|------|-------------|
27
+ | `onTestRenewal` | `() => void` | Simulate subscription renewal |
28
+ | `onCheckCredits` | `() => void` | Show current credits in alert |
29
+ | `onTestDuplicate` | `() => void` | Test duplicate renewal protection |
30
+
31
+ ## Important Notes
32
+
33
+ โš ๏ธ **Development Only**
34
+ - This hook only works in `__DEV__` mode
35
+ - Returns `undefined` in production builds
36
+ - Use for testing and development purposes only
37
+
38
+ ## Basic Usage
39
+
40
+ ```typescript
41
+ function DevTestSection() {
42
+ const devCallbacks = useDevTestCallbacks();
43
+
44
+ // Don't render in production
45
+ if (!devCallbacks) return null;
46
+
47
+ const { onTestRenewal, onCheckCredits, onTestDuplicate } = devCallbacks;
48
+
49
+ return (
50
+ <View style={styles.devSection}>
51
+ <Text style={styles.title}>Developer Tools</Text>
52
+
53
+ <Button onPress={onTestRenewal} title="Test Renewal" />
54
+ <Button onPress={onCheckCredits} title="Check Credits" />
55
+ <Button onPress={onTestDuplicate} title="Test Duplicate Protection" />
56
+ </View>
57
+ );
58
+ }
59
+ ```
60
+
61
+ ## Advanced Usage
62
+
63
+ ### Complete Dev Test Panel
64
+
65
+ ```typescript
66
+ function DevTestPanel() {
67
+ const devCallbacks = useDevTestCallbacks();
68
+
69
+ if (!__DEV__ || !devCallbacks) return null;
70
+
71
+ const { onTestRenewal, onCheckCredits, onTestDuplicate } = devCallbacks;
72
+
73
+ return (
74
+ <ScrollView style={styles.devPanel}>
75
+ <Text style={styles.header}>Developer Test Panel</Text>
76
+
77
+ <View style={styles.section}>
78
+ <Text style={styles.sectionTitle}>Renewal Testing</Text>
79
+
80
+ <TouchableOpacity
81
+ style={styles.button}
82
+ onPress={onTestRenewal}
83
+ >
84
+ <Text>Test Renewal (Add Credits)</Text>
85
+ </TouchableOpacity>
86
+
87
+ <Text style={styles.help}>
88
+ Simulates a subscription renewal and adds credits using ACCUMULATE mode
89
+ </Text>
90
+ </View>
91
+
92
+ <View style={styles.section}>
93
+ <Text style={styles.sectionTitle}>Credits Inspection</Text>
94
+
95
+ <TouchableOpacity
96
+ style={styles.button}
97
+ onPress={onCheckCredits}
98
+ >
99
+ <Text>Check Current Credits</Text>
100
+ </TouchableOpacity>
101
+
102
+ <Text style={styles.help}>
103
+ Display current credit balance and purchase date
104
+ </Text>
105
+ </View>
106
+
107
+ <View style={styles.section}>
108
+ <Text style={styles.sectionTitle}>Duplicate Protection</Text>
109
+
110
+ <TouchableOpacity
111
+ style={styles.button}
112
+ onPress={onTestDuplicate}
113
+ >
114
+ <Text>Test Duplicate Protection</Text>
115
+ </TouchableOpacity>
116
+
117
+ <Text style={styles.help}>
118
+ Tests that duplicate renewals with the same ID are prevented
119
+ </Text>
120
+ </View>
121
+ </ScrollView>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ### With Settings Screen Integration
127
+
128
+ ```typescript
129
+ function SettingsScreen() {
130
+ const devCallbacks = useDevTestCallbacks();
131
+
132
+ return (
133
+ <ScrollView>
134
+ <Section title="Account">
135
+ <SettingsItem label="Email" value={user?.email} />
136
+ <SettingsItem label="Subscription" value={isPremium ? 'Premium' : 'Free'} />
137
+ </Section>
138
+
139
+ {/* Only show in development */}
140
+ {__DEV__ && devCallbacks && (
141
+ <Section title="Developer Tools">
142
+ <SettingsItem
143
+ label="Test Renewal"
144
+ onPress={devCallbacks.onTestRenewal}
145
+ />
146
+ <SettingsItem
147
+ label="Check Credits"
148
+ onPress={devCallbacks.onCheckCredits}
149
+ />
150
+ <SettingsItem
151
+ label="Test Duplicate Protection"
152
+ onPress={devCallbacks.onTestDuplicate}
153
+ />
154
+ </Section>
155
+ )}
156
+ </ScrollView>
157
+ );
158
+ }
159
+ ```
160
+
161
+ ### With Debug Menu
162
+
163
+ ```typescript
164
+ function DebugMenu() {
165
+ const devCallbacks = useDevTestCallbacks();
166
+
167
+ if (!__DEV__) return null;
168
+
169
+ return (
170
+ <Menu>
171
+ {devCallbacks && (
172
+ <>
173
+ <MenuItem onPress={devCallbacks.onTestRenewal}>
174
+ Test Renewal
175
+ </MenuItem>
176
+ <MenuItem onPress={devCallbacks.onCheckCredits}>
177
+ Check Credits
178
+ </MenuItem>
179
+ <MenuItem onPress={devCallbacks.onTestDuplicate}>
180
+ Test Duplicate Protection
181
+ </MenuItem>
182
+ </>
183
+ )}
184
+ </Menu>
185
+ );
186
+ }
187
+ ```
188
+
189
+ ## Test Functions
190
+
191
+ ### onTestRenewal
192
+
193
+ Simulates a subscription renewal event:
194
+
195
+ ```typescript
196
+ const onTestRenewal = () => {
197
+ // Simulates renewal with:
198
+ // - renewalId: `dev_renewal_${Date.now()}`
199
+ // - productId: 'test_yearly_subscription'
200
+ // - Mode: ACCUMULATE (adds to existing credits)
201
+
202
+ // Shows alert with:
203
+ // - New credit balance
204
+ // - Confirmation of ACCUMULATE mode
205
+ };
206
+ ```
207
+
208
+ **Example output:**
209
+ ```
210
+ โœ… Test Renewal Success
211
+ Credits Updated!
212
+
213
+ New Balance: 1200
214
+
215
+ (ACCUMULATE mode - credits added to existing)
216
+ ```
217
+
218
+ ### onCheckCredits
219
+
220
+ Displays current credit information:
221
+
222
+ ```typescript
223
+ const onCheckCredits = () => {
224
+ // Shows alert with:
225
+ // - Current credit balance
226
+ // - Purchase date (or "N/A")
227
+ };
228
+ ```
229
+
230
+ **Example output:**
231
+ ```
232
+ ๐Ÿ“Š Current Credits
233
+ Credits: 100
234
+
235
+ Purchased: January 15, 2024
236
+ ```
237
+
238
+ ### onTestDuplicate
239
+
240
+ Tests duplicate renewal protection:
241
+
242
+ ```typescript
243
+ const onTestDuplicate = () => {
244
+ // Performs two initialization calls with same renewalId:
245
+ // - First call: Adds credits
246
+ // - Second call: Should be skipped
247
+
248
+ // Shows alert with:
249
+ // - First call result
250
+ // - Second call result (should indicate protection worked)
251
+ };
252
+ ```
253
+
254
+ **Example output:**
255
+ ```
256
+ Duplicate Test
257
+ First call: โœ… Added credits
258
+
259
+ Second call: โœ… Skipped (protection works!)
260
+ ```
261
+
262
+ ## Development Logging
263
+
264
+ The hook logs detailed information in development:
265
+
266
+ ```typescript
267
+ // Test renewal
268
+ ๐Ÿงช [Dev Test] Simulating auto-renewal...
269
+ {
270
+ userId: 'user-123',
271
+ renewalId: 'dev_renewal_1705311234567'
272
+ }
273
+ โœ… [Dev Test] Renewal completed:
274
+ {
275
+ success: true,
276
+ credits: 1100
277
+ }
278
+
279
+ // Check credits
280
+ ๐Ÿ“Š Current Credits
281
+ Credits: 100
282
+ Purchased: January 15, 2024
283
+
284
+ // Test duplicate
285
+ ๐Ÿงช [Dev Test] Testing duplicate protection...
286
+ First call: { credits: 100, ... }
287
+ Second call: { credits: 100, ... }
288
+ ```
289
+
290
+ ## Examples
291
+
292
+ ### Comprehensive Dev Dashboard
293
+
294
+ ```typescript
295
+ function DevDashboard() {
296
+ const devCallbacks = useDevTestCallbacks();
297
+
298
+ if (!__DEV__ || !devCallbacks) return null;
299
+
300
+ const { user } = useAuth();
301
+ const { credits } = useCredits();
302
+
303
+ return (
304
+ <View style={styles.dashboard}>
305
+ <View style={styles.header}>
306
+ <Text style={styles.title}>Development Dashboard</Text>
307
+ <Text style={styles.subtitle}>
308
+ User: {user?.uid || 'Not logged in'}
309
+ </Text>
310
+ <Text style={styles.subtitle}>
311
+ Credits: {credits?.credits || 0}
312
+ </Text>
313
+ </View>
314
+
315
+ <View style={styles.actions}>
316
+ <TouchableOpacity
317
+ style={styles.actionButton}
318
+ onPress={devCallbacks.onTestRenewal}
319
+ >
320
+ <Icon name="refresh" size={20} />
321
+ <Text>Simulate Renewal</Text>
322
+ </TouchableOpacity>
323
+
324
+ <TouchableOpacity
325
+ style={styles.actionButton}
326
+ onPress={devCallbacks.onCheckCredits}
327
+ >
328
+ <Icon name="search" size={20} />
329
+ <Text>Inspect Credits</Text>
330
+ </TouchableOpacity>
331
+
332
+ <TouchableOpacity
333
+ style={styles.actionButton}
334
+ onPress={devCallbacks.onTestDuplicate}
335
+ >
336
+ <Icon name="shield" size={20} />
337
+ <Text>Test Duplicate Protection</Text>
338
+ </TouchableOpacity>
339
+ </View>
340
+
341
+ <View style={styles.info}>
342
+ <Text style={styles.infoTitle}>Test Mode Active</Text>
343
+ <Text style={styles.infoText}>
344
+ All operations use test data and won't affect production
345
+ </Text>
346
+ </View>
347
+ </View>
348
+ );
349
+ }
350
+ ```
351
+
352
+ ### With Flow Testing
353
+
354
+ ```typescript
355
+ function RenewalFlowTest() {
356
+ const devCallbacks = useDevTestCallbacks();
357
+
358
+ if (!__DEV__ || !devCallbacks) return null;
359
+
360
+ const testRenewalFlow = async () => {
361
+ // 1. Check initial credits
362
+ devCallbacks.onCheckCredits();
363
+
364
+ // 2. Simulate renewal
365
+ await new Promise(resolve => setTimeout(resolve, 1000));
366
+ devCallbacks.onTestRenewal();
367
+
368
+ // 3. Verify credits increased
369
+ await new Promise(resolve => setTimeout(resolve, 1000));
370
+ devCallbacks.onCheckCredits();
371
+
372
+ // 4. Test duplicate protection
373
+ await new Promise(resolve => setTimeout(resolve, 1000));
374
+ devCallbacks.onTestDuplicate();
375
+ };
376
+
377
+ return (
378
+ <Button
379
+ onPress={testRenewalFlow}
380
+ title="Run Complete Renewal Flow Test"
381
+ />
382
+ );
383
+ }
384
+ ```
385
+
386
+ ## Best Practices
387
+
388
+ 1. **Development only** - Never use in production code
389
+ 2. **Guard with `__DEV__`** - Always check if in development mode
390
+ 3. **Clear UI** - Make dev tools visually distinct
391
+ 4. **Test thoroughly** - Use for testing renewal flows
392
+ 5. **Document behavior** - Leave clear comments for other developers
393
+ 6. **Remove before release** - Ensure dev UI doesn't ship
394
+ 7. **Test edge cases** - Duplicate handling, error cases
395
+
396
+ ## Production Safety
397
+
398
+ The hook is production-safe:
399
+
400
+ ```typescript
401
+ export const useDevTestCallbacks = (): DevTestActions | undefined => {
402
+ // ... implementation
403
+
404
+ if (!__DEV__) {
405
+ return undefined; // โœ… Returns undefined in production
406
+ }
407
+
408
+ return { onTestRenewal, onCheckCredits, onTestDuplicate };
409
+ };
410
+ ```
411
+
412
+ ## Related Hooks
413
+
414
+ - **useCredits** - For accessing credits balance
415
+ - **useInitializeCredits** - For credit initialization
416
+ - **usePremiumWithCredits** - For premium + credits integration
417
+
418
+ ## See Also
419
+
420
+ - [Credits README](../../../domains/wallet/README.md)
421
+ - [Renewal Testing Guide](../../../docs/RENEWAL_TESTING.md)
422
+ - [Development Tools](../../../docs/DEV_TOOLS.md)