@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.
- package/LICENSE +21 -0
- package/README.md +462 -0
- package/package.json +3 -3
- package/src/application/README.md +229 -0
- package/src/application/ports/README.md +103 -0
- package/src/domain/README.md +402 -0
- package/src/domain/constants/README.md +80 -0
- package/src/domain/entities/README.md +176 -0
- package/src/domain/errors/README.md +307 -0
- package/src/domain/value-objects/README.md +186 -0
- package/src/domains/config/README.md +390 -0
- package/src/domains/paywall/README.md +371 -0
- package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
- package/src/domains/paywall/components/README.md +185 -0
- package/src/domains/paywall/entities/README.md +199 -0
- package/src/domains/paywall/hooks/README.md +129 -0
- package/src/domains/wallet/README.md +292 -0
- package/src/domains/wallet/domain/README.md +108 -0
- package/src/domains/wallet/domain/entities/README.md +122 -0
- package/src/domains/wallet/domain/errors/README.md +157 -0
- package/src/domains/wallet/infrastructure/README.md +96 -0
- package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
- package/src/domains/wallet/presentation/components/README.md +231 -0
- package/src/domains/wallet/presentation/hooks/README.md +255 -0
- package/src/infrastructure/README.md +514 -0
- package/src/infrastructure/mappers/README.md +34 -0
- package/src/infrastructure/models/README.md +26 -0
- package/src/infrastructure/repositories/README.md +385 -0
- package/src/infrastructure/services/README.md +374 -0
- package/src/presentation/README.md +410 -0
- package/src/presentation/components/README.md +183 -0
- package/src/presentation/components/details/CreditRow.md +337 -0
- package/src/presentation/components/details/DetailRow.md +283 -0
- package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
- package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
- package/src/presentation/components/details/README.md +449 -0
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
- package/src/presentation/components/feedback/README.md +447 -0
- package/src/presentation/components/paywall/PaywallModal.md +444 -0
- package/src/presentation/components/paywall/README.md +190 -0
- package/src/presentation/components/sections/README.md +468 -0
- package/src/presentation/components/sections/SubscriptionSection.md +246 -0
- package/src/presentation/hooks/README.md +743 -0
- package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
- package/src/presentation/hooks/useAuthGate.md +403 -0
- package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
- package/src/presentation/hooks/useCreditChecker.md +407 -0
- package/src/presentation/hooks/useCredits.md +342 -0
- package/src/presentation/hooks/useCreditsGate.md +346 -0
- package/src/presentation/hooks/useDeductCredit.md +160 -0
- package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
- package/src/presentation/hooks/useFeatureGate.md +157 -0
- package/src/presentation/hooks/useInitializeCredits.md +458 -0
- package/src/presentation/hooks/usePaywall.md +334 -0
- package/src/presentation/hooks/usePaywallOperations.md +486 -0
- package/src/presentation/hooks/usePaywallVisibility.md +344 -0
- package/src/presentation/hooks/usePremium.md +230 -0
- package/src/presentation/hooks/usePremiumGate.md +423 -0
- package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
- package/src/presentation/hooks/useSubscription.md +450 -0
- package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
- package/src/presentation/hooks/useSubscriptionGate.md +168 -0
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
- package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
- package/src/presentation/hooks/useUserTier.md +356 -0
- package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
- package/src/presentation/screens/README.md +194 -0
- package/src/presentation/types/README.md +38 -0
- package/src/presentation/utils/README.md +52 -0
- package/src/revenuecat/README.md +523 -0
- package/src/revenuecat/domain/README.md +147 -0
- package/src/revenuecat/domain/errors/README.md +197 -0
- package/src/revenuecat/infrastructure/config/README.md +40 -0
- package/src/revenuecat/infrastructure/managers/README.md +49 -0
- package/src/revenuecat/presentation/hooks/README.md +56 -0
- package/src/revenuecat/presentation/hooks/usePurchasePackage.ts +1 -1
- package/src/utils/README.md +529 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# Utils
|
|
2
|
+
|
|
3
|
+
Abonelik sistemi için yardımcı fonksiyonlar ve utility araçları.
|
|
4
|
+
|
|
5
|
+
## İçindekiler
|
|
6
|
+
|
|
7
|
+
- [Premium Utilities](#premium-utilities)
|
|
8
|
+
- [User Tier Utilities](#user-tier-utilities)
|
|
9
|
+
- [Package Utilities](#package-utilities)
|
|
10
|
+
- [Price Utilities](#price-utilities)
|
|
11
|
+
- [Async Utilities](#async-utilities)
|
|
12
|
+
- [Type Definitions](#type-definitions)
|
|
13
|
+
|
|
14
|
+
## Premium Utilities
|
|
15
|
+
|
|
16
|
+
Premium durum kontrolü ve yönetimi için yardımcı fonksiyonlar.
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import {
|
|
20
|
+
isPremiumStatus,
|
|
21
|
+
isSubscriptionActive,
|
|
22
|
+
getSubscriptionStatusText,
|
|
23
|
+
hasPremiumAccess,
|
|
24
|
+
canAccessPremiumFeature,
|
|
25
|
+
} from '@umituz/react-native-subscription';
|
|
26
|
+
|
|
27
|
+
// Premium durum kontrolü
|
|
28
|
+
const premium = isPremiumStatus({
|
|
29
|
+
type: 'premium',
|
|
30
|
+
isActive: true,
|
|
31
|
+
isPremium: true,
|
|
32
|
+
});
|
|
33
|
+
// true
|
|
34
|
+
|
|
35
|
+
// Aktif abonelik kontrolü
|
|
36
|
+
const active = isSubscriptionActive({
|
|
37
|
+
isActive: true,
|
|
38
|
+
expirationDate: '2025-12-31',
|
|
39
|
+
});
|
|
40
|
+
// true
|
|
41
|
+
|
|
42
|
+
// Durum metni
|
|
43
|
+
const text = getSubscriptionStatusText({
|
|
44
|
+
type: 'premium',
|
|
45
|
+
isActive: true,
|
|
46
|
+
});
|
|
47
|
+
// "Active Premium"
|
|
48
|
+
|
|
49
|
+
// Premium erişim kontrolü
|
|
50
|
+
const hasAccess = hasPremiumAccess({
|
|
51
|
+
type: 'premium',
|
|
52
|
+
isActive: true,
|
|
53
|
+
isPremium: true,
|
|
54
|
+
});
|
|
55
|
+
// true
|
|
56
|
+
|
|
57
|
+
// Özellik erişimi kontrolü
|
|
58
|
+
const canAccess = canAccessPremiumFeature(
|
|
59
|
+
{ type: 'premium', isActive: true },
|
|
60
|
+
'ai_tools'
|
|
61
|
+
);
|
|
62
|
+
// true
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## User Tier Utilities
|
|
66
|
+
|
|
67
|
+
Kullanıcı tier yönetimi için yardımcı fonksiyonlar.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import {
|
|
71
|
+
getUserTier,
|
|
72
|
+
isGuestUser,
|
|
73
|
+
isFreeUser,
|
|
74
|
+
isPremiumUser,
|
|
75
|
+
getTierPriority,
|
|
76
|
+
canUpgradeTier,
|
|
77
|
+
getNextTier,
|
|
78
|
+
} from '@umituz/react-native-subscription';
|
|
79
|
+
|
|
80
|
+
// Tier belirleme
|
|
81
|
+
const tier = getUserTier({
|
|
82
|
+
isAuthenticated: false,
|
|
83
|
+
});
|
|
84
|
+
// 'guest'
|
|
85
|
+
|
|
86
|
+
const tier = getUserTier({
|
|
87
|
+
isAuthenticated: true,
|
|
88
|
+
subscription: { type: 'free', isActive: false },
|
|
89
|
+
});
|
|
90
|
+
// 'free'
|
|
91
|
+
|
|
92
|
+
const tier = getUserTier({
|
|
93
|
+
isAuthenticated: true,
|
|
94
|
+
subscription: { type: 'premium', isActive: true },
|
|
95
|
+
});
|
|
96
|
+
// 'premium'
|
|
97
|
+
|
|
98
|
+
// Tier kontrolü
|
|
99
|
+
const guest = isGuestUser({ isAuthenticated: false });
|
|
100
|
+
// true
|
|
101
|
+
|
|
102
|
+
const free = isFreeUser({ type: 'free' });
|
|
103
|
+
// true
|
|
104
|
+
|
|
105
|
+
const premium = isPremiumUser({ type: 'premium', isActive: true });
|
|
106
|
+
// true
|
|
107
|
+
|
|
108
|
+
// Tier önceliği
|
|
109
|
+
const priority = getTierPriority('premium'); // 3
|
|
110
|
+
const priority = getTierPriority('free'); // 2
|
|
111
|
+
const priority = getTierPriority('guest'); // 1
|
|
112
|
+
|
|
113
|
+
// Tier upgrade kontrolü
|
|
114
|
+
const canUpgrade = canUpgradeTier('free', 'premium');
|
|
115
|
+
// true
|
|
116
|
+
|
|
117
|
+
// Sonraki tier
|
|
118
|
+
const next = getNextTier('guest');
|
|
119
|
+
// 'free'
|
|
120
|
+
const next = getNextTier('free');
|
|
121
|
+
// 'premium'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Package Utilities
|
|
125
|
+
|
|
126
|
+
RevenueCat paketleri ile çalışmak için yardımcı fonksiyonlar.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import {
|
|
130
|
+
getPackageType,
|
|
131
|
+
isSubscriptionPackage,
|
|
132
|
+
isInAppPurchase,
|
|
133
|
+
filterPackagesByType,
|
|
134
|
+
sortPackagesByPrice,
|
|
135
|
+
getPackagePeriod,
|
|
136
|
+
getAnnualPackage,
|
|
137
|
+
getMonthlyPackage,
|
|
138
|
+
formatPackageTitle,
|
|
139
|
+
} from '@umituz/react-native-subscription';
|
|
140
|
+
|
|
141
|
+
// Paket tipi
|
|
142
|
+
const type = getPackageType({
|
|
143
|
+
identifier: 'com.app.premium.monthly',
|
|
144
|
+
packageType: PACKAGE_TYPE.MONTHLY,
|
|
145
|
+
});
|
|
146
|
+
// 'MONTHLY'
|
|
147
|
+
|
|
148
|
+
// Abonelik kontrolü
|
|
149
|
+
const isSub = isSubscriptionPackage({
|
|
150
|
+
packageType: PACKAGE_TYPE.MONTHLY,
|
|
151
|
+
});
|
|
152
|
+
// true
|
|
153
|
+
|
|
154
|
+
const isInApp = isInAppPurchase({
|
|
155
|
+
packageType: PACKAGE_TYPE.ONE_TIME_PURCHASE,
|
|
156
|
+
});
|
|
157
|
+
// true
|
|
158
|
+
|
|
159
|
+
// Paket filtreleme
|
|
160
|
+
const subs = filterPackagesByType(packages, 'subscription');
|
|
161
|
+
const inApps = filterPackagesByType(packages, 'inapp');
|
|
162
|
+
|
|
163
|
+
// Fiyata göre sıralama
|
|
164
|
+
const sorted = sortPackagesByPrice(packages, 'asc');
|
|
165
|
+
|
|
166
|
+
// Periyot alma
|
|
167
|
+
const period = getPackagePeriod('com.app.premium.monthly');
|
|
168
|
+
// 'monthly'
|
|
169
|
+
const period = getPackagePeriod('com.app.premium.annual');
|
|
170
|
+
// 'annual'
|
|
171
|
+
|
|
172
|
+
// Yıllık paket
|
|
173
|
+
const annual = getAnnualPackage(packages);
|
|
174
|
+
|
|
175
|
+
// Aylık paket
|
|
176
|
+
const monthly = getMonthlyPackage(packages);
|
|
177
|
+
|
|
178
|
+
// Paket başlığı formatlama
|
|
179
|
+
const title = formatPackageTitle({
|
|
180
|
+
product: {
|
|
181
|
+
title: 'Premium Monthly',
|
|
182
|
+
price: 9.99,
|
|
183
|
+
},
|
|
184
|
+
}, 'en');
|
|
185
|
+
// "Premium Monthly - $9.99"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Price Utilities
|
|
189
|
+
|
|
190
|
+
Fiyat hesaplama ve formatlama fonksiyonları.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import {
|
|
194
|
+
formatPrice,
|
|
195
|
+
formatPriceWithCurrency,
|
|
196
|
+
calculateDiscount,
|
|
197
|
+
calculateSavings,
|
|
198
|
+
getPricePerMonth,
|
|
199
|
+
getCreditsPerDollar,
|
|
200
|
+
getAnnualMonthlyPrice,
|
|
201
|
+
} from '@umituz/react-native-subscription';
|
|
202
|
+
|
|
203
|
+
// Fiyat formatlama
|
|
204
|
+
const formatted = formatPrice(9.99, 'USD');
|
|
205
|
+
// "$9.99"
|
|
206
|
+
|
|
207
|
+
const formattedTRY = formatPrice(99.99, 'TRY');
|
|
208
|
+
// "99,99 ₺"
|
|
209
|
+
|
|
210
|
+
// Currency ile formatlama
|
|
211
|
+
const withCurrency = formatPriceWithCurrency(9.99, 'USD', 'en-US');
|
|
212
|
+
// "$9.99"
|
|
213
|
+
|
|
214
|
+
const withCurrencyTRY = formatPriceWithCurrency(99.99, 'TRY', 'tr-TR');
|
|
215
|
+
// "99,99 ₺"
|
|
216
|
+
|
|
217
|
+
// İndirim hesaplama
|
|
218
|
+
const discount = calculateDiscount(19.99, 14.99);
|
|
219
|
+
// 25.012506253126564 (%25)
|
|
220
|
+
|
|
221
|
+
// Tasarruf hesaplama
|
|
222
|
+
const savings = calculateSavings(9.99, 12); // Monthly price vs 12 months
|
|
223
|
+
// 119.88
|
|
224
|
+
|
|
225
|
+
// Aylık fiyat
|
|
226
|
+
const monthly = getPricePerMonth(79.99, 'annual');
|
|
227
|
+
// 6.67
|
|
228
|
+
|
|
229
|
+
// Kredi/dolar oranı
|
|
230
|
+
const creditsPerDollar = getCreditsPerDollar(100, 0.99);
|
|
231
|
+
// 101.01
|
|
232
|
+
|
|
233
|
+
// Yıllık aylık fiyat
|
|
234
|
+
const annualMonthly = getAnnualMonthlyPrice(79.99);
|
|
235
|
+
// "$6.67/month"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Period Utilities
|
|
239
|
+
|
|
240
|
+
Abonelik periyodu ile ilgili yardımcı fonksiyonlar.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import {
|
|
244
|
+
getPeriodInMonths,
|
|
245
|
+
getPeriodInDays,
|
|
246
|
+
formatPeriod,
|
|
247
|
+
isMonthly,
|
|
248
|
+
isAnnual,
|
|
249
|
+
isLifetime,
|
|
250
|
+
getPeriodType,
|
|
251
|
+
} from '@umituz/react-native-subscription';
|
|
252
|
+
|
|
253
|
+
// Periyodun ay sayısı
|
|
254
|
+
const months = getPeriodInMonths('monthly'); // 1
|
|
255
|
+
const months = getPeriodInMonths('annual'); // 12
|
|
256
|
+
const months = getPeriodInMonths('lifetime'); // null
|
|
257
|
+
|
|
258
|
+
// Periyodun gün sayısı
|
|
259
|
+
const days = getPeriodInDays('monthly'); // 30
|
|
260
|
+
const days = getPeriodInDays('annual'); // 365
|
|
261
|
+
const days = getPeriodInDays('lifetime'); // null
|
|
262
|
+
|
|
263
|
+
// Periyot formatlama
|
|
264
|
+
const formatted = formatPeriod('monthly', 'en');
|
|
265
|
+
// "Monthly"
|
|
266
|
+
const formatted = formatPeriod('annual', 'en');
|
|
267
|
+
// "Annual"
|
|
268
|
+
const formatted = formatPeriod('monthly', 'tr');
|
|
269
|
+
// "Aylık"
|
|
270
|
+
|
|
271
|
+
// Periyot kontrolü
|
|
272
|
+
const isMonth = isMonthly('monthly'); // true
|
|
273
|
+
const isYear = isAnnual('annual'); // true
|
|
274
|
+
const isLife = isLifetime('lifetime'); // true
|
|
275
|
+
|
|
276
|
+
// Periyot tipi
|
|
277
|
+
const type = getPeriodType('com.app.premium.monthly');
|
|
278
|
+
// 'monthly'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Async Utilities
|
|
282
|
+
|
|
283
|
+
Asenkron işlemler için yardımcı fonksiyonlar.
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import {
|
|
287
|
+
checkPremiumStatusAsync,
|
|
288
|
+
getSubscriptionStatusAsync,
|
|
289
|
+
waitForSubscriptionInit,
|
|
290
|
+
retryOperation,
|
|
291
|
+
} from '@umituz/react-native-subscription';
|
|
292
|
+
|
|
293
|
+
// Premium kontrolü (async)
|
|
294
|
+
const isPremium = await checkPremiumStatusAsync(userId);
|
|
295
|
+
// true/false
|
|
296
|
+
|
|
297
|
+
// Abonelik durumu (async)
|
|
298
|
+
const status = await getSubscriptionStatusAsync(userId);
|
|
299
|
+
// { type: 'premium', isActive: true, ... }
|
|
300
|
+
|
|
301
|
+
// Başlatma bekleme
|
|
302
|
+
await waitForSubscriptionInit({
|
|
303
|
+
timeout: 5000,
|
|
304
|
+
interval: 100,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Retry ile işlem
|
|
308
|
+
const result = await retryOperation(
|
|
309
|
+
async () => {
|
|
310
|
+
return await fetchSubscriptionStatus();
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
maxRetries: 3,
|
|
314
|
+
delay: 1000,
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Type Definitions
|
|
320
|
+
|
|
321
|
+
Yardımcı tip tanımlamaları.
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
import type {
|
|
325
|
+
PackagePeriod,
|
|
326
|
+
PackageType,
|
|
327
|
+
UserTier,
|
|
328
|
+
SubscriptionStatusType,
|
|
329
|
+
PriceFormatOptions,
|
|
330
|
+
PeriodFormatOptions,
|
|
331
|
+
} from '@umituz/react-native-subscription';
|
|
332
|
+
|
|
333
|
+
// Periyot tipi
|
|
334
|
+
type PackagePeriod = 'monthly' | 'annual' | 'lifetime';
|
|
335
|
+
|
|
336
|
+
// Paket tipi
|
|
337
|
+
type PackageType = 'subscription' | 'inapp';
|
|
338
|
+
|
|
339
|
+
// Kullanıcı tier
|
|
340
|
+
type UserTier = 'guest' | 'free' | 'premium';
|
|
341
|
+
|
|
342
|
+
// Durum tipi
|
|
343
|
+
type SubscriptionStatusType = 'unknown' | 'guest' | 'free' | 'premium';
|
|
344
|
+
|
|
345
|
+
// Fiyat format seçenekleri
|
|
346
|
+
interface PriceFormatOptions {
|
|
347
|
+
locale?: string;
|
|
348
|
+
currencyDisplay?: 'symbol' | 'code' | 'name';
|
|
349
|
+
minimumFractionDigits?: number;
|
|
350
|
+
maximumFractionDigits?: number;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Periyot format seçenekleri
|
|
354
|
+
interface PeriodFormatOptions {
|
|
355
|
+
locale?: string;
|
|
356
|
+
lowercase?: boolean;
|
|
357
|
+
abbreviated?: boolean;
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Validation Utilities
|
|
362
|
+
|
|
363
|
+
Validasyon fonksiyonları.
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
import {
|
|
367
|
+
isValidPackageId,
|
|
368
|
+
isValidPrice,
|
|
369
|
+
isValidPeriod,
|
|
370
|
+
validateSubscriptionData,
|
|
371
|
+
isValidEmail,
|
|
372
|
+
} from '@umituz/react-native-subscription';
|
|
373
|
+
|
|
374
|
+
// Paket ID validasyonu
|
|
375
|
+
const valid = isValidPackageId('com.app.premium.monthly');
|
|
376
|
+
// true
|
|
377
|
+
|
|
378
|
+
const invalid = isValidPackageId('invalid-package');
|
|
379
|
+
// false
|
|
380
|
+
|
|
381
|
+
// Fiyat validasyonu
|
|
382
|
+
const valid = isValidPrice(9.99);
|
|
383
|
+
// true
|
|
384
|
+
|
|
385
|
+
const invalid = isValidPrice(-9.99);
|
|
386
|
+
// false
|
|
387
|
+
|
|
388
|
+
// Periyot validasyonu
|
|
389
|
+
const valid = isValidPeriod('monthly');
|
|
390
|
+
// true
|
|
391
|
+
|
|
392
|
+
const invalid = isValidPeriod('invalid');
|
|
393
|
+
// false
|
|
394
|
+
|
|
395
|
+
// Abonelik verisi validasyonu
|
|
396
|
+
const validation = validateSubscriptionData({
|
|
397
|
+
type: 'premium',
|
|
398
|
+
isActive: true,
|
|
399
|
+
isPremium: true,
|
|
400
|
+
expirationDate: '2025-12-31',
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
if (!validation.isValid) {
|
|
404
|
+
console.error('Validation errors:', validation.errors);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Email validasyonu
|
|
408
|
+
const valid = isValidEmail('user@example.com');
|
|
409
|
+
// true
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Data Transformation Utilities
|
|
413
|
+
|
|
414
|
+
Veri dönüşüm fonksiyonları.
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
import {
|
|
418
|
+
transformRevenueCatPackage,
|
|
419
|
+
transformSubscriptionStatus,
|
|
420
|
+
normalizePackageData,
|
|
421
|
+
sanitizeUserData,
|
|
422
|
+
} from '@umituz/react-native-subscription';
|
|
423
|
+
|
|
424
|
+
// RevenueCat paketi dönüştürme
|
|
425
|
+
const transformed = transformRevenueCatPackage(revenueCatPackage);
|
|
426
|
+
// { id: 'premium_monthly', period: 'monthly', price: 9.99, ... }
|
|
427
|
+
|
|
428
|
+
// Abonelik durumu dönüştürme
|
|
429
|
+
const status = transformSubscriptionStatus(rawData);
|
|
430
|
+
// SubscriptionStatus objesi
|
|
431
|
+
|
|
432
|
+
// Paket verisi normalize etme
|
|
433
|
+
const normalized = normalizePackageData(packages);
|
|
434
|
+
// Standart paket formatı
|
|
435
|
+
|
|
436
|
+
// Kullanıcı verisi temizleme
|
|
437
|
+
const cleaned = sanitizeUserData({
|
|
438
|
+
userId: 'user-123',
|
|
439
|
+
// ...sensitive data removed
|
|
440
|
+
});
|
|
441
|
+
// Temizlenmiş kullanıcı verisi
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Best Practices
|
|
445
|
+
|
|
446
|
+
1. **Type Safety**: Tüm fonksiyonlar tip güvenlidir
|
|
447
|
+
2. **Null Safety**: Null check'leri güvenli şekilde yapın
|
|
448
|
+
3. **Error Handling**: Hataları yakalayın ve handle edin
|
|
449
|
+
4. **Localization**: Farklı dilleri destekleyin
|
|
450
|
+
5. **Testing**: Utility fonksiyonlarını test edin
|
|
451
|
+
6. **Documentation**: JSDoc yorumları ekleyin
|
|
452
|
+
|
|
453
|
+
## Örnek Kullanım
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
import {
|
|
457
|
+
getUserTier,
|
|
458
|
+
isPremiumUser,
|
|
459
|
+
formatPrice,
|
|
460
|
+
getPackagePeriod,
|
|
461
|
+
calculateDiscount,
|
|
462
|
+
} from '@umituz/react-native-subscription';
|
|
463
|
+
|
|
464
|
+
function SubscriptionCard({ subscription, package }) {
|
|
465
|
+
// Tier belirleme
|
|
466
|
+
const tier = getUserTier(subscription);
|
|
467
|
+
|
|
468
|
+
// Premium kontrolü
|
|
469
|
+
const isPremium = isPremiumUser(subscription);
|
|
470
|
+
|
|
471
|
+
// Fiyat formatlama
|
|
472
|
+
const formattedPrice = formatPrice(package.price, package.currency);
|
|
473
|
+
|
|
474
|
+
// Periyot alma
|
|
475
|
+
const period = getPackagePeriod(package.identifier);
|
|
476
|
+
|
|
477
|
+
// İndirim hesaplama
|
|
478
|
+
const discount = calculateDiscount(
|
|
479
|
+
package.price,
|
|
480
|
+
package.originalPrice
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
return (
|
|
484
|
+
<View>
|
|
485
|
+
<Text>Tier: {tier}</Text>
|
|
486
|
+
<Text>Price: {formattedPrice}</Text>
|
|
487
|
+
<Text>Period: {period}</Text>
|
|
488
|
+
{discount > 0 && <Text>Save {discount.toFixed(0)}%</Text>}
|
|
489
|
+
</View>
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
## Testing
|
|
495
|
+
|
|
496
|
+
Utility fonksiyonları test etmek kolaydır:
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
import { getUserTier, formatPrice } from '@umituz/react-native-subscription';
|
|
500
|
+
|
|
501
|
+
describe('Utils', () => {
|
|
502
|
+
describe('getUserTier', () => {
|
|
503
|
+
it('should return guest for unauthenticated users', () => {
|
|
504
|
+
const tier = getUserTier({ isAuthenticated: false });
|
|
505
|
+
expect(tier).toBe('guest');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('should return premium for active subscriptions', () => {
|
|
509
|
+
const tier = getUserTier({
|
|
510
|
+
isAuthenticated: true,
|
|
511
|
+
subscription: { type: 'premium', isActive: true },
|
|
512
|
+
});
|
|
513
|
+
expect(tier).toBe('premium');
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
describe('formatPrice', () => {
|
|
518
|
+
it('should format USD prices correctly', () => {
|
|
519
|
+
const formatted = formatPrice(9.99, 'USD');
|
|
520
|
+
expect(formatted).toBe('$9.99');
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it('should format TRY prices correctly', () => {
|
|
524
|
+
const formatted = formatPrice(99.99, 'TRY');
|
|
525
|
+
expect(formatted).toBe('99,99 ₺');
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
```
|