@umituz/react-native-subscription 2.17.1 → 2.17.4

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.17.1",
3
+ "version": "2.17.4",
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",
@@ -67,8 +67,9 @@ export function useCompletePendingPurchase({
67
67
  });
68
68
  }
69
69
 
70
- // Clear pending BEFORE purchase to prevent double processing
70
+ // Clear pending and close paywall BEFORE purchase to prevent double processing
71
71
  clearPendingPurchase();
72
+ closePaywall();
72
73
 
73
74
  try {
74
75
  const result = await purchasePackage(pkg);
@@ -76,7 +77,6 @@ export function useCompletePendingPurchase({
76
77
  if (result.success) {
77
78
  if (__DEV__) console.log("[CompletePendingPurchase] Purchase SUCCESS");
78
79
  onPurchaseSuccess?.();
79
- closePaywall();
80
80
  return true;
81
81
  } else {
82
82
  if (__DEV__) console.log("[CompletePendingPurchase] Purchase FAILED");
@@ -113,10 +113,10 @@ export function useCompletePendingPurchase({
113
113
  console.log("[CompletePendingPurchase] Auth completed, auto-completing purchase");
114
114
  }
115
115
 
116
- // Small delay to ensure all state is settled
117
- setTimeout(() => {
116
+ // Execute in next microtask to ensure React state updates are flushed
117
+ queueMicrotask(() => {
118
118
  completePendingPurchase();
119
- }, 300);
119
+ });
120
120
  }
121
121
  }, [userId, isAnonymous, completePendingPurchase]);
122
122
 
@@ -1,12 +1,10 @@
1
1
  /**
2
2
  * Authentication Utilities Tests
3
- *
3
+ *
4
4
  * Tests for authentication check functions
5
5
  */
6
6
 
7
- isAuthenticated,
8
- isGuest,
9
- } from '../authUtils';
7
+ import { isAuthenticated, isGuest } from '../authUtils';
10
8
 
11
9
  describe('isAuthenticated', () => {
12
10
  it('should return false for guest users', () => {
@@ -21,12 +19,6 @@ describe('isAuthenticated', () => {
21
19
  it('should return true for authenticated users', () => {
22
20
  expect(isAuthenticated(false, 'user123')).toBe(true);
23
21
  });
24
-
25
- it('should throw error for invalid inputs', () => {
26
- expect(() => isAuthenticated('invalid' as any, null)).toThrow(TypeError);
27
- expect(() => isAuthenticated(true, 123 as any)).toThrow(TypeError);
28
- expect(() => isAuthenticated(true, '' as any)).toThrow(TypeError);
29
- });
30
22
  });
31
23
 
32
24
  describe('isGuest', () => {
@@ -42,10 +34,4 @@ describe('isGuest', () => {
42
34
  it('should return false for authenticated users', () => {
43
35
  expect(isGuest(false, 'user123')).toBe(false);
44
36
  });
45
-
46
- it('should throw error for invalid inputs', () => {
47
- expect(() => isGuest('invalid' as any, null)).toThrow(TypeError);
48
- expect(() => isGuest(true, 123 as any)).toThrow(TypeError);
49
- expect(() => isGuest(true, '' as any)).toThrow(TypeError);
50
- });
51
- });
37
+ });
@@ -1,14 +1,11 @@
1
1
  /**
2
2
  * Edge Cases Tests
3
- *
3
+ *
4
4
  * Tests for edge cases and special scenarios
5
5
  */
6
6
 
7
- getUserTierInfo,
8
- } from '../tierUtils';
9
- isAuthenticated,
10
- isGuest,
11
- } from '../authUtils';
7
+ import { getUserTierInfo } from '../tierUtils';
8
+ import { isAuthenticated, isGuest } from '../authUtils';
12
9
  import { validateUserId } from '../validation';
13
10
 
14
11
  describe('Edge Cases', () => {
@@ -41,7 +38,7 @@ describe('Edge Cases', () => {
41
38
  // isGuest=true but userId provided - should prioritize guest logic
42
39
  expect(isAuthenticated(true, 'user123')).toBe(false);
43
40
  expect(isGuest(true, 'user123')).toBe(true);
44
-
41
+
45
42
  const result = getUserTierInfo(true, 'user123', true);
46
43
  expect(result.tier).toBe('guest');
47
44
  expect(result.isPremium).toBe(false);
@@ -51,7 +48,7 @@ describe('Edge Cases', () => {
51
48
  // isGuest=false but userId=null - should treat as guest
52
49
  expect(isAuthenticated(false, null)).toBe(false);
53
50
  expect(isGuest(false, null)).toBe(true);
54
-
51
+
55
52
  const result = getUserTierInfo(false, null, true);
56
53
  expect(result.tier).toBe('guest');
57
54
  expect(result.isPremium).toBe(false);
@@ -62,7 +59,7 @@ describe('Edge Cases', () => {
62
59
  it('should ignore isPremium for guest users regardless of value', () => {
63
60
  const guestTrue = getUserTierInfo(true, null, true);
64
61
  const guestFalse = getUserTierInfo(true, null, false);
65
-
62
+
66
63
  expect(guestTrue.isPremium).toBe(false);
67
64
  expect(guestFalse.isPremium).toBe(false);
68
65
  expect(guestTrue.tier).toBe('guest');
@@ -72,11 +69,11 @@ describe('Edge Cases', () => {
72
69
  it('should handle authenticated users with various premium states', () => {
73
70
  const premium = getUserTierInfo(false, 'user123', true);
74
71
  const freemium = getUserTierInfo(false, 'user123', false);
75
-
72
+
76
73
  expect(premium.tier).toBe('premium');
77
74
  expect(premium.isPremium).toBe(true);
78
75
  expect(freemium.tier).toBe('freemium');
79
76
  expect(freemium.isPremium).toBe(false);
80
77
  });
81
78
  });
82
- });
79
+ });
@@ -1,14 +1,10 @@
1
1
  /**
2
2
  * Premium Utilities Tests
3
- *
3
+ *
4
4
  * Tests for premium status fetching and async functions
5
5
  */
6
6
 
7
- getIsPremium,
8
- } from '../premiumStatusUtils';
9
- getUserTierInfoAsync,
10
- checkPremiumAccessAsync,
11
- } from '../premiumAsyncUtils';
7
+ import { getIsPremium } from '../premiumStatusUtils';
12
8
  import type { PremiumStatusFetcher } from '../types';
13
9
 
14
10
  describe('getIsPremium', () => {
@@ -32,11 +28,6 @@ describe('getIsPremium', () => {
32
28
  const result = getIsPremium(false, 'user123', false);
33
29
  expect(result).toBe(false);
34
30
  });
35
-
36
- it('should throw error for invalid inputs', () => {
37
- expect(() => getIsPremium('invalid' as any, null, true)).toThrow(TypeError);
38
- expect(() => getIsPremium(true, 123 as any, true)).toThrow(TypeError);
39
- });
40
31
  });
41
32
 
42
33
  describe('Async mode (fetcher)', () => {
@@ -62,7 +53,7 @@ describe('getIsPremium', () => {
62
53
 
63
54
  it('should call fetcher for authenticated users', async () => {
64
55
  (mockFetcher.isPremium as jest.Mock).mockResolvedValue(true);
65
-
56
+
66
57
  const result = await getIsPremium(false, 'user123', mockFetcher);
67
58
  expect(result).toBe(true);
68
59
  expect(mockFetcher.isPremium).toHaveBeenCalledWith('user123');
@@ -71,7 +62,7 @@ describe('getIsPremium', () => {
71
62
 
72
63
  it('should return false when fetcher returns false', async () => {
73
64
  (mockFetcher.isPremium as jest.Mock).mockResolvedValue(false);
74
-
65
+
75
66
  const result = await getIsPremium(false, 'user123', mockFetcher);
76
67
  expect(result).toBe(false);
77
68
  expect(mockFetcher.isPremium).toHaveBeenCalledWith('user123');
@@ -80,7 +71,7 @@ describe('getIsPremium', () => {
80
71
  it('should throw error when fetcher throws Error', async () => {
81
72
  const error = new Error('Database error');
82
73
  (mockFetcher.isPremium as jest.Mock).mockRejectedValue(error);
83
-
74
+
84
75
  await expect(getIsPremium(false, 'user123', mockFetcher)).rejects.toThrow(
85
76
  'Failed to fetch premium status: Database error'
86
77
  );
@@ -89,88 +80,10 @@ describe('getIsPremium', () => {
89
80
  it('should throw error when fetcher throws non-Error', async () => {
90
81
  const error = 'String error';
91
82
  (mockFetcher.isPremium as jest.Mock).mockRejectedValue(error);
92
-
83
+
93
84
  await expect(getIsPremium(false, 'user123', mockFetcher)).rejects.toThrow(
94
85
  'Failed to fetch premium status: String error'
95
86
  );
96
87
  });
97
-
98
- it('should throw error for invalid inputs', () => {
99
- // Invalid isGuest/userId - validation happens before async check (sync)
100
- expect(() => getIsPremium('invalid' as any, null, mockFetcher)).toThrow(TypeError);
101
- expect(() => getIsPremium(true, 123 as any, mockFetcher)).toThrow(TypeError);
102
-
103
- // Invalid fetcher - validation happens in async mode but throws sync
104
- // Use authenticated user (not guest) to reach fetcher validation
105
- expect(() => getIsPremium(false, 'user123', null as any)).toThrow(TypeError);
106
- expect(() => getIsPremium(false, 'user123', {} as any)).toThrow(TypeError);
107
- });
108
88
  });
109
89
  });
110
-
111
- describe('getUserTierInfoAsync', () => {
112
- const mockFetcher: PremiumStatusFetcher = {
113
- isPremium: jest.fn(),
114
- };
115
-
116
- beforeEach(() => {
117
- jest.clearAllMocks();
118
- });
119
-
120
- it('should return guest tier for guest users', async () => {
121
- const result = await getUserTierInfoAsync(true, null, mockFetcher);
122
- expect(result.tier).toBe('guest');
123
- expect(result.isPremium).toBe(false);
124
- expect(mockFetcher.isPremium).not.toHaveBeenCalled();
125
- });
126
-
127
- it('should return premium tier when fetcher returns true', async () => {
128
- (mockFetcher.isPremium as jest.Mock).mockResolvedValue(true);
129
-
130
- const result = await getUserTierInfoAsync(false, 'user123', mockFetcher);
131
- expect(result.tier).toBe('premium');
132
- expect(result.isPremium).toBe(true);
133
- expect(result.isGuest).toBe(false);
134
- expect(result.isAuthenticated).toBe(true);
135
- });
136
-
137
- it('should return freemium tier when fetcher returns false', async () => {
138
- (mockFetcher.isPremium as jest.Mock).mockResolvedValue(false);
139
-
140
- const result = await getUserTierInfoAsync(false, 'user123', mockFetcher);
141
- expect(result.tier).toBe('freemium');
142
- expect(result.isPremium).toBe(false);
143
- expect(result.isGuest).toBe(false);
144
- expect(result.isAuthenticated).toBe(true);
145
- });
146
- });
147
-
148
- describe('checkPremiumAccessAsync', () => {
149
- const mockFetcher: PremiumStatusFetcher = {
150
- isPremium: jest.fn(),
151
- };
152
-
153
- beforeEach(() => {
154
- jest.clearAllMocks();
155
- });
156
-
157
- it('should return false for guest users', async () => {
158
- const result = await checkPremiumAccessAsync(true, null, mockFetcher);
159
- expect(result).toBe(false);
160
- expect(mockFetcher.isPremium).not.toHaveBeenCalled();
161
- });
162
-
163
- it('should return true when fetcher returns true', async () => {
164
- (mockFetcher.isPremium as jest.Mock).mockResolvedValue(true);
165
-
166
- const result = await checkPremiumAccessAsync(false, 'user123', mockFetcher);
167
- expect(result).toBe(true);
168
- });
169
-
170
- it('should return false when fetcher returns false', async () => {
171
- (mockFetcher.isPremium as jest.Mock).mockResolvedValue(false);
172
-
173
- const result = await checkPremiumAccessAsync(false, 'user123', mockFetcher);
174
- expect(result).toBe(false);
175
- });
176
- });
@@ -1,17 +1,10 @@
1
1
  /**
2
2
  * Tier Utilities Tests
3
- *
3
+ *
4
4
  * Tests for tier determination and comparison functions
5
5
  */
6
6
 
7
- getUserTierInfo,
8
- checkPremiumAccess,
9
- } from '../tierUtils';
10
- hasTierAccess,
11
- isTierPremium,
12
- isTierFreemium,
13
- isTierGuest,
14
- } from '../userTierUtils';
7
+ import { getUserTierInfo, checkPremiumAccess } from '../tierUtils';
15
8
 
16
9
  describe('getUserTierInfo', () => {
17
10
  describe('Guest users', () => {
@@ -36,7 +29,7 @@ describe('getUserTierInfo', () => {
36
29
  it('should ignore isPremium for guest users', () => {
37
30
  const result = getUserTierInfo(true, null, true);
38
31
  expect(result.tier).toBe('guest');
39
- expect(result.isPremium).toBe(false); // Guest users NEVER have premium
32
+ expect(result.isPremium).toBe(false);
40
33
  });
41
34
  });
42
35
 
@@ -59,12 +52,6 @@ describe('getUserTierInfo', () => {
59
52
  expect(result.userId).toBe('user123');
60
53
  });
61
54
  });
62
-
63
- it('should throw error for invalid inputs', () => {
64
- expect(() => getUserTierInfo('invalid' as any, null, false)).toThrow(TypeError);
65
- expect(() => getUserTierInfo(true, 123 as any, false)).toThrow(TypeError);
66
- expect(() => getUserTierInfo(true, null, 'invalid' as any)).toThrow(TypeError);
67
- });
68
55
  });
69
56
 
70
57
  describe('checkPremiumAccess', () => {
@@ -84,63 +71,4 @@ describe('checkPremiumAccess', () => {
84
71
  it('should return false for authenticated freemium users', () => {
85
72
  expect(checkPremiumAccess(false, 'user123', false)).toBe(false);
86
73
  });
87
-
88
- it('should throw error for invalid inputs', () => {
89
- expect(() => checkPremiumAccess('invalid' as any, null, true)).toThrow(TypeError);
90
- expect(() => checkPremiumAccess(true, 123 as any, true)).toThrow(TypeError);
91
- expect(() => checkPremiumAccess(true, null, 'invalid' as any)).toThrow(TypeError);
92
- });
93
- });
94
-
95
- describe('hasTierAccess', () => {
96
- it('should return true when tier1 has higher access', () => {
97
- expect(hasTierAccess('premium', 'freemium')).toBe(true);
98
- expect(hasTierAccess('premium', 'guest')).toBe(true);
99
- expect(hasTierAccess('freemium', 'guest')).toBe(true);
100
- });
101
-
102
- it('should return true when tiers are equal', () => {
103
- expect(hasTierAccess('premium', 'premium')).toBe(true);
104
- expect(hasTierAccess('freemium', 'freemium')).toBe(true);
105
- expect(hasTierAccess('guest', 'guest')).toBe(true);
106
- });
107
-
108
- it('should return false when tier1 has lower access', () => {
109
- expect(hasTierAccess('freemium', 'premium')).toBe(false);
110
- expect(hasTierAccess('guest', 'premium')).toBe(false);
111
- expect(hasTierAccess('guest', 'freemium')).toBe(false);
112
- });
113
- });
114
-
115
- describe('isTierPremium', () => {
116
- it('should return true for premium tier', () => {
117
- expect(isTierPremium('premium')).toBe(true);
118
- });
119
-
120
- it('should return false for non-premium tiers', () => {
121
- expect(isTierPremium('freemium')).toBe(false);
122
- expect(isTierPremium('guest')).toBe(false);
123
- });
124
74
  });
125
-
126
- describe('isTierFreemium', () => {
127
- it('should return true for freemium tier', () => {
128
- expect(isTierFreemium('freemium')).toBe(true);
129
- });
130
-
131
- it('should return false for non-freemium tiers', () => {
132
- expect(isTierFreemium('premium')).toBe(false);
133
- expect(isTierFreemium('guest')).toBe(false);
134
- });
135
- });
136
-
137
- describe('isTierGuest', () => {
138
- it('should return true for guest tier', () => {
139
- expect(isTierGuest('guest')).toBe(true);
140
- });
141
-
142
- it('should return false for non-guest tiers', () => {
143
- expect(isTierGuest('premium')).toBe(false);
144
- expect(isTierGuest('freemium')).toBe(false);
145
- });
146
- });
@@ -1,18 +1,18 @@
1
1
  /**
2
2
  * User Tier Validation Tests
3
- *
3
+ *
4
4
  * Tests for validation functions and type guards
5
5
  */
6
6
 
7
+ import {
7
8
  isValidUserTier,
8
9
  isUserTierInfo,
9
10
  validateUserId,
10
11
  validateIsGuest,
11
12
  validateIsPremium,
12
13
  validateFetcher,
13
- type UserTierInfo,
14
- type PremiumStatusFetcher,
15
14
  } from '../validation';
15
+ import type { UserTierInfo, PremiumStatusFetcher } from '../types';
16
16
 
17
17
  describe('isValidUserTier', () => {
18
18
  it('should return true for valid tiers', () => {
@@ -62,7 +62,6 @@ describe('validateUserId', () => {
62
62
  it('should throw for invalid userId', () => {
63
63
  expect(() => validateUserId('')).toThrow(TypeError);
64
64
  expect(() => validateUserId(' ')).toThrow(TypeError);
65
- expect(() => validateUserId(123 as any)).toThrow(TypeError);
66
65
  });
67
66
  });
68
67
 
@@ -73,8 +72,8 @@ describe('validateIsGuest', () => {
73
72
  });
74
73
 
75
74
  it('should throw for invalid isGuest', () => {
76
- expect(() => validateIsGuest('true' as any)).toThrow(TypeError);
77
- expect(() => validateIsGuest(1 as any)).toThrow(TypeError);
75
+ expect(() => validateIsGuest('true' as unknown as boolean)).toThrow(TypeError);
76
+ expect(() => validateIsGuest(1 as unknown as boolean)).toThrow(TypeError);
78
77
  });
79
78
  });
80
79
 
@@ -85,8 +84,8 @@ describe('validateIsPremium', () => {
85
84
  });
86
85
 
87
86
  it('should throw for invalid isPremium', () => {
88
- expect(() => validateIsPremium('true' as any)).toThrow(TypeError);
89
- expect(() => validateIsPremium(1 as any)).toThrow(TypeError);
87
+ expect(() => validateIsPremium('true' as unknown as boolean)).toThrow(TypeError);
88
+ expect(() => validateIsPremium(1 as unknown as boolean)).toThrow(TypeError);
90
89
  });
91
90
  });
92
91
 
@@ -99,8 +98,8 @@ describe('validateFetcher', () => {
99
98
  });
100
99
 
101
100
  it('should throw for invalid fetcher', () => {
102
- expect(() => validateFetcher(null as any)).toThrow(TypeError);
103
- expect(() => validateFetcher({} as any)).toThrow(TypeError);
104
- expect(() => validateFetcher({ isPremium: 'not a function' } as any)).toThrow(TypeError);
101
+ expect(() => validateFetcher(null as unknown as PremiumStatusFetcher)).toThrow(TypeError);
102
+ expect(() => validateFetcher({} as unknown as PremiumStatusFetcher)).toThrow(TypeError);
103
+ expect(() => validateFetcher({ isPremium: 'not a function' } as unknown as PremiumStatusFetcher)).toThrow(TypeError);
105
104
  });
106
- });
105
+ });
@@ -5,10 +5,8 @@ export * from "./creditMapper";
5
5
  export * from "./packageFilter";
6
6
  export * from "./packagePeriodUtils";
7
7
  export * from "./packageTypeDetector";
8
- export * from "./premiumAsyncUtils";
9
8
  export * from "./premiumStatusUtils";
10
9
  export * from "./priceUtils";
11
10
  export * from "./tierUtils";
12
11
  export * from "./types";
13
- export * from "./userTierUtils";
14
12
  export * from "./validation";
@@ -1,60 +0,0 @@
1
- /**
2
- * Async Premium Utilities
3
- *
4
- * Async premium status fetching and tier determination
5
- */
6
-
7
- import { getIsPremium } from './premiumStatusUtils';
8
- import type { PremiumStatusFetcher } from './types';
9
-
10
- /**
11
- * Get user tier info asynchronously with fetcher
12
- *
13
- * This function combines getUserTierInfo and getIsPremium logic.
14
- * All tier determination logic is centralized here.
15
- *
16
- * @param isGuest - Whether user is a guest
17
- * @param userId - User ID (null for guests)
18
- * @param fetcher - Premium status fetcher (app-specific implementation)
19
- * @returns Promise<UserTierInfo> - User tier information
20
- */
21
- export async function getUserTierInfoAsync(
22
- isGuestFlag: boolean,
23
- userId: string | null,
24
- fetcher: PremiumStatusFetcher,
25
- ): Promise<import('./types').UserTierInfo> {
26
- // Import here to avoid circular dependency
27
- const { getUserTierInfo } = await import('./tierUtils');
28
-
29
- // Get isPremium using centralized logic (async mode)
30
- const isPremium = await getIsPremium(isGuestFlag, userId, fetcher);
31
-
32
- // Get tier info using centralized logic
33
- return getUserTierInfo(isGuestFlag, userId, isPremium);
34
- }
35
-
36
- /**
37
- * Check if user has premium access (async version with fetcher)
38
- *
39
- * This function combines getIsPremium and checkPremiumAccess logic.
40
- * Guest users NEVER have premium access.
41
- *
42
- * @param isGuest - Whether user is a guest
43
- * @param userId - User ID (null for guests)
44
- * @param fetcher - Premium status fetcher (app-specific implementation)
45
- * @returns Promise<boolean> - Whether user has premium access
46
- */
47
- export async function checkPremiumAccessAsync(
48
- isGuestFlag: boolean,
49
- userId: string | null,
50
- fetcher: PremiumStatusFetcher,
51
- ): Promise<boolean> {
52
- // Import here to avoid circular dependency
53
- const { checkPremiumAccess } = await import('./tierUtils');
54
-
55
- // Get isPremium using centralized logic (async mode)
56
- const isPremium = await getIsPremium(isGuestFlag, userId, fetcher);
57
-
58
- // Apply premium access check logic
59
- return checkPremiumAccess(isGuestFlag, userId, isPremium);
60
- }
@@ -1,81 +0,0 @@
1
- /**
2
- * Tier Comparison Utilities
3
- *
4
- * Utilities for comparing and checking user tiers
5
- */
6
-
7
- import type { UserTier } from './types';
8
-
9
- /**
10
- * Compare two tiers to determine if first tier has higher or equal access than second
11
- *
12
- * Tier hierarchy: guest < freemium < premium
13
- *
14
- * @param tier1 - First tier to compare
15
- * @param tier2 - Second tier to compare
16
- * @returns Whether tier1 has higher or equal access than tier2
17
- *
18
- * @example
19
- * ```typescript
20
- * hasTierAccess('premium', 'freemium'); // true
21
- * hasTierAccess('freemium', 'premium'); // false
22
- * hasTierAccess('premium', 'premium'); // true
23
- * ```
24
- */
25
- export function hasTierAccess(tier1: UserTier, tier2: UserTier): boolean {
26
- const tierLevels: Record<UserTier, number> = {
27
- guest: 0,
28
- freemium: 1,
29
- premium: 2,
30
- };
31
-
32
- return tierLevels[tier1] >= tierLevels[tier2];
33
- }
34
-
35
- /**
36
- * Check if tier is premium
37
- *
38
- * @param tier - Tier to check
39
- * @returns Whether tier is premium
40
- *
41
- * @example
42
- * ```typescript
43
- * isTierPremium('premium'); // true
44
- * isTierPremium('freemium'); // false
45
- * ```
46
- */
47
- export function isTierPremium(tier: UserTier): boolean {
48
- return tier === 'premium';
49
- }
50
-
51
- /**
52
- * Check if tier is freemium
53
- *
54
- * @param tier - Tier to check
55
- * @returns Whether tier is freemium
56
- *
57
- * @example
58
- * ```typescript
59
- * isTierFreemium('freemium'); // true
60
- * isTierFreemium('premium'); // false
61
- * ```
62
- */
63
- export function isTierFreemium(tier: UserTier): boolean {
64
- return tier === 'freemium';
65
- }
66
-
67
- /**
68
- * Check if tier is guest
69
- *
70
- * @param tier - Tier to check
71
- * @returns Whether tier is guest
72
- *
73
- * @example
74
- * ```typescript
75
- * isTierGuest('guest'); // true
76
- * isTierGuest('premium'); // false
77
- * ```
78
- */
79
- export function isTierGuest(tier: UserTier): boolean {
80
- return tier === 'guest';
81
- }