@umituz/react-native-subscription 2.14.98 → 2.14.99

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.
@@ -0,0 +1,373 @@
1
+ # RevenueCat Domain Types
2
+
3
+ Type definitions and type utilities for RevenueCat integration.
4
+
5
+ ## Overview
6
+
7
+ This directory contains TypeScript type definitions, type guards, and utility types used throughout the RevenueCat integration.
8
+
9
+ ## Core Types
10
+
11
+ ### PurchasesError
12
+
13
+ Error type for RevenueCat operations.
14
+
15
+ ```typescript
16
+ interface PurchasesError {
17
+ code: string;
18
+ message: string;
19
+ underlyingErrorMessage?: string;
20
+ readableErrorMessage?: string;
21
+ }
22
+
23
+ type PurchasesErrorCode =
24
+ | 'UNKNOWN_ERROR'
25
+ | 'NETWORK_ERROR'
26
+ | 'INVALID_CREDENTIALS_ERROR'
27
+ | 'OPERATION_ALREADY_IN_PROGRESS'
28
+ | 'PRODUCT_NOT_AVAILABLE_FOR_PURCHASE'
29
+ | 'INVALIDreceipt_ERROR'
30
+ | 'MISSING_RECEIPT_ERROR'
31
+ | 'INVALID_APP_USER_ID_ERROR'
32
+ | 'CONFLICTING_SUBS_ERROR'
33
+ | 'CUSTOMER_INFO_ERROR'
34
+ | 'INVALID_CONFIGURATION_ERROR'
35
+ | 'UNSUPPORTED_OPERATION_ERROR'
36
+ | 'PURCHASE_CANCELLED'
37
+ | 'PURCHASE_INVALID'
38
+ | 'PRODUCT_ALREADY_OWNED'
39
+ | 'RECEIPT_ALREADY_IN_USE'
40
+ | 'INVALID_OFFERINGS_ERROR'
41
+ | 'INVALID_ELIGIBILITY_ERROR'
42
+ | 'INELIGIBLE_FOR_INTRO_PRICING'
43
+ | 'EXPIRED_RECEIPT_ERROR';
44
+ ```
45
+
46
+ ### PackageType
47
+
48
+ Available package types.
49
+
50
+ ```typescript
51
+ type PackageType =
52
+ | 'monthly'
53
+ | 'annual'
54
+ | 'lifetime'
55
+ | 'weekly'
56
+ | 'single_purchase';
57
+ ```
58
+
59
+ ### ProductType
60
+
61
+ Types of products.
62
+
63
+ ```typescript
64
+ type ProductType =
65
+ | 'subscription'
66
+ | 'non_subscription'
67
+ | 'consumable';
68
+ ```
69
+
70
+ ### PeriodType
71
+
72
+ Subscription period types.
73
+
74
+ ```typescript
75
+ type PeriodType =
76
+ | 'normal'
77
+ | 'trial'
78
+ | 'intro';
79
+ ```
80
+
81
+ ### Store
82
+
83
+ Available app stores.
84
+
85
+ ```typescript
86
+ type Store =
87
+ | 'app_store'
88
+ | 'play_store'
89
+ | 'stripe'
90
+ | 'mac_app_store'
91
+ | 'play_store_amazon'
92
+ | 'promotional';
93
+ ```
94
+
95
+ ### SubscriptionStatus
96
+
97
+ Subscription status representation.
98
+
99
+ ```typescript
100
+ type SubscriptionStatus =
101
+ | 'active'
102
+ | 'expired'
103
+ | 'cancelled'
104
+ | 'in_billing_retry'
105
+ | 'paused';
106
+
107
+ interface SubscriptionInfo {
108
+ status: SubscriptionStatus;
109
+ expiresAt: Date | null;
110
+ willRenew: boolean;
111
+ periodType: PeriodType;
112
+ isTrial: boolean;
113
+ isIntro: boolean;
114
+ isSandbox: boolean;
115
+ }
116
+ ```
117
+
118
+ ## Type Guards
119
+
120
+ ### isPurchasesError
121
+
122
+ Check if an error is a PurchasesError.
123
+
124
+ ```typescript
125
+ function isPurchasesError(error: unknown): error is PurchasesError {
126
+ return (
127
+ typeof error === 'object' &&
128
+ error !== null &&
129
+ 'code' in error &&
130
+ 'message' in error
131
+ );
132
+ }
133
+ ```
134
+
135
+ ### isActiveEntitlement
136
+
137
+ Check if entitlement is active.
138
+
139
+ ```typescript
140
+ function isActiveEntitlement(
141
+ entitlement: EntitlementInfo | null
142
+ ): entitlement is EntitlementInfo & { isActive: true } {
143
+ return entitlement?.isActive === true;
144
+ }
145
+ ```
146
+
147
+ ### isSubscriptionProduct
148
+
149
+ Check if product is a subscription.
150
+
151
+ ```typescript
152
+ function isSubscriptionProduct(
153
+ product: Product
154
+ ): product is Product & { type: 'subscription' } {
155
+ return product.type === 'subscription';
156
+ }
157
+ ```
158
+
159
+ ### isConsumableProduct
160
+
161
+ Check if product is consumable.
162
+
163
+ ```typescript
164
+ function isConsumableProduct(
165
+ product: Product
166
+ ): product is Product & { type: 'consumable' } {
167
+ return product.type === 'consumable';
168
+ }
169
+ ```
170
+
171
+ ## Utility Types
172
+
173
+ ### PurchaseResult
174
+
175
+ Result of a purchase operation.
176
+
177
+ ```typescript
178
+ type PurchaseResult =
179
+ | { success: true; customerInfo: CustomerInfo; transaction: Transaction }
180
+ | { success: false; error: PurchasesError };
181
+ ```
182
+
183
+ ### RestoreResult
184
+
185
+ Result of a restore operation.
186
+
187
+ ```typescript
188
+ type RestoreResult =
189
+ | { success: true; customerInfo: CustomerInfo }
190
+ | { success: false; error: PurchasesError };
191
+ ```
192
+
193
+ ### EntitlementCheckResult
194
+
195
+ Result of checking an entitlement.
196
+
197
+ ```typescript
198
+ type EntitlementCheckResult =
199
+ | { hasAccess: true; entitlement: EntitlementInfo }
200
+ | { hasAccess: false; reason: 'not_entitled' | 'expired' | 'cancelled' };
201
+ ```
202
+
203
+ ### OfferingConfig
204
+
205
+ Configuration for an offering.
206
+
207
+ ```typescript
208
+ interface OfferingConfig {
209
+ identifier: string;
210
+ metadata?: {
211
+ highlight?: boolean;
212
+ recommended?: boolean;
213
+ discount_percentage?: number;
214
+ features?: string[];
215
+ };
216
+ }
217
+ ```
218
+
219
+ ### PurchaseConfig
220
+
221
+ Configuration for purchase flow.
222
+
223
+ ```typescript
224
+ interface PurchaseConfig {
225
+ onPurchaseStarted?: () => void;
226
+ onPurchaseSuccess?: (result: PurchaseResult) => void;
227
+ onPurchaseError?: (error: PurchasesError) => void;
228
+ onPurchaseCancelled?: () => void;
229
+ }
230
+ ```
231
+
232
+ ## Usage Examples
233
+
234
+ ### Using Type Guards
235
+
236
+ ```typescript
237
+ import { isPurchasesError, isActiveEntitlement } from './types';
238
+
239
+ try {
240
+ const result = await purchasePackage(pkg);
241
+ } catch (error) {
242
+ if (isPurchasesError(error)) {
243
+ // Now TypeScript knows error is PurchasesError
244
+ console.error('Error code:', error.code);
245
+ console.error('Message:', error.message);
246
+ }
247
+ }
248
+
249
+ // Checking entitlements
250
+ const premium = customerInfo.entitlements.premium;
251
+ if (isActiveEntitlement(premium)) {
252
+ // TypeScript knows premium is active
253
+ console.log('Premium expires:', premium.expirationDate);
254
+ }
255
+ ```
256
+
257
+ ### Using Utility Types
258
+
259
+ ```typescript
260
+ async function handlePurchase(
261
+ pkg: Package
262
+ ): Promise<PurchaseResult> {
263
+ try {
264
+ const result = await revenueCatService.purchasePackage(pkg);
265
+ return {
266
+ success: true,
267
+ customerInfo: result.customerInfo,
268
+ transaction: result.transaction,
269
+ };
270
+ } catch (error) {
271
+ if (isPurchasesError(error)) {
272
+ return {
273
+ success: false,
274
+ error,
275
+ };
276
+ }
277
+ throw error;
278
+ }
279
+ }
280
+
281
+ // Usage
282
+ const result = await handlePurchase(selectedPackage);
283
+
284
+ if (result.success) {
285
+ console.log('Purchased:', result.transaction?.transactionIdentifier);
286
+ } else {
287
+ console.error('Failed:', result.error.message);
288
+ }
289
+ ```
290
+
291
+ ### Checking Entitlements
292
+
293
+ ```typescript
294
+ function checkEntitlement(
295
+ customerInfo: CustomerInfo,
296
+ entitlementId: string
297
+ ): EntitlementCheckResult {
298
+ const entitlement = customerInfo.entitlements[entitlementId];
299
+
300
+ if (!entitlement) {
301
+ return { hasAccess: false, reason: 'not_entitled' };
302
+ }
303
+
304
+ if (!entitlement.isActive) {
305
+ if (entitlement.expirationDate && entitlement.expirationDate < new Date()) {
306
+ return { hasAccess: false, reason: 'expired' };
307
+ }
308
+ if (entitlement.unsubscribeDetectedAt) {
309
+ return { hasAccess: false, reason: 'cancelled' };
310
+ }
311
+ return { hasAccess: false, reason: 'not_entitled' };
312
+ }
313
+
314
+ return { hasAccess: true, entitlement };
315
+ }
316
+
317
+ // Usage
318
+ const check = checkEntitlement(customerInfo, 'premium');
319
+
320
+ if (check.hasAccess) {
321
+ console.log('Premium active');
322
+ } else {
323
+ console.log('Reason:', check.reason);
324
+ }
325
+ ```
326
+
327
+ ## Type Assertions
328
+
329
+ ### Assert Subscription Status
330
+
331
+ ```typescript
332
+ function getSubscriptionStatus(
333
+ entitlement: EntitlementInfo | null
334
+ ): SubscriptionStatus {
335
+ if (!entitlement || !entitlement.isActive) {
336
+ return 'expired';
337
+ }
338
+
339
+ if (entitlement.billingIssueDetectedAt) {
340
+ return 'in_billing_retry';
341
+ }
342
+
343
+ if (entitlement.unsubscribeDetectedAt && !entitlement.willRenew) {
344
+ return 'cancelled';
345
+ }
346
+
347
+ return 'active';
348
+ }
349
+ ```
350
+
351
+ ### Assert Product Type
352
+
353
+ ```typescript
354
+ function getProductPrice(
355
+ product: Product
356
+ ): string | null {
357
+ if (isSubscriptionProduct(product)) {
358
+ return product.price.formattedPrice;
359
+ }
360
+
361
+ if (isConsumableProduct(product)) {
362
+ return product.price.formattedPrice;
363
+ }
364
+
365
+ return null;
366
+ }
367
+ ```
368
+
369
+ ## Related
370
+
371
+ - [RevenueCat Domain](../README.md)
372
+ - [RevenueCat Entities](../entities/README.md)
373
+ - [RevenueCat Value Objects](../value-objects/README.md)