@umituz/react-native-auth 1.12.0 → 2.0.1

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 (136) hide show
  1. package/README.md +0 -0
  2. package/lib/__tests__/services/AuthCoreService.test.d.ts +4 -0
  3. package/lib/__tests__/services/AuthCoreService.test.js +198 -0
  4. package/lib/__tests__/services/AuthPackage.test.d.ts +4 -0
  5. package/lib/__tests__/services/AuthPackage.test.js +177 -0
  6. package/lib/__tests__/services/GuestModeService.test.d.ts +4 -0
  7. package/lib/__tests__/services/GuestModeService.test.js +141 -0
  8. package/lib/__tests__/utils/AuthValidation.test.d.ts +4 -0
  9. package/lib/__tests__/utils/AuthValidation.test.js +222 -0
  10. package/lib/application/ports/IAuthProvider.d.ts +42 -0
  11. package/lib/application/ports/IAuthProvider.js +5 -0
  12. package/lib/application/ports/IAuthService.d.ts +48 -0
  13. package/lib/application/ports/IAuthService.js +5 -0
  14. package/lib/domain/entities/AuthUser.d.ts +12 -0
  15. package/lib/domain/entities/AuthUser.js +5 -0
  16. package/lib/domain/errors/AuthError.d.ts +36 -0
  17. package/lib/domain/errors/AuthError.js +76 -0
  18. package/lib/domain/value-objects/AuthConfig.d.ts +16 -0
  19. package/lib/domain/value-objects/AuthConfig.js +14 -0
  20. package/lib/index.d.ts +45 -0
  21. package/lib/index.js +59 -0
  22. package/lib/infrastructure/adapters/StorageProviderAdapter.d.ts +16 -0
  23. package/lib/infrastructure/adapters/StorageProviderAdapter.js +72 -0
  24. package/lib/infrastructure/adapters/UIProviderAdapter.d.ts +18 -0
  25. package/lib/infrastructure/adapters/UIProviderAdapter.js +28 -0
  26. package/lib/infrastructure/providers/FirebaseAuthProvider.d.ts +19 -0
  27. package/lib/infrastructure/providers/FirebaseAuthProvider.js +94 -0
  28. package/lib/infrastructure/services/AuthCoreService.d.ts +22 -0
  29. package/lib/infrastructure/services/AuthCoreService.js +102 -0
  30. package/lib/infrastructure/services/AuthEventService.d.ts +28 -0
  31. package/lib/infrastructure/services/AuthEventService.js +88 -0
  32. package/lib/infrastructure/services/AuthPackage.d.ts +62 -0
  33. package/lib/infrastructure/services/AuthPackage.js +91 -0
  34. package/lib/infrastructure/services/AuthService.d.ts +42 -0
  35. package/lib/infrastructure/services/AuthService.js +123 -0
  36. package/lib/infrastructure/services/GuestModeService.d.ts +23 -0
  37. package/lib/infrastructure/services/GuestModeService.js +69 -0
  38. package/lib/infrastructure/storage/GuestModeStorage.d.ts +16 -0
  39. package/lib/infrastructure/storage/GuestModeStorage.js +73 -0
  40. package/lib/infrastructure/utils/AuthErrorMapper.d.ts +8 -0
  41. package/lib/infrastructure/utils/AuthErrorMapper.js +51 -0
  42. package/lib/infrastructure/utils/AuthEventEmitter.d.ts +12 -0
  43. package/lib/infrastructure/utils/AuthEventEmitter.js +25 -0
  44. package/lib/infrastructure/utils/AuthValidation.d.ts +49 -0
  45. package/lib/infrastructure/utils/AuthValidation.js +133 -0
  46. package/lib/infrastructure/utils/UserMapper.d.ts +15 -0
  47. package/lib/infrastructure/utils/UserMapper.js +16 -0
  48. package/lib/presentation/components/AuthContainer.d.ts +10 -0
  49. package/lib/presentation/components/AuthContainer.js +27 -0
  50. package/lib/presentation/components/AuthDivider.d.ts +6 -0
  51. package/lib/presentation/components/AuthDivider.js +36 -0
  52. package/lib/presentation/components/AuthErrorDisplay.d.ts +10 -0
  53. package/lib/presentation/components/AuthErrorDisplay.js +24 -0
  54. package/lib/presentation/components/AuthFormCard.d.ts +10 -0
  55. package/lib/presentation/components/AuthFormCard.js +19 -0
  56. package/lib/presentation/components/AuthGradientBackground.d.ts +6 -0
  57. package/lib/presentation/components/AuthGradientBackground.js +8 -0
  58. package/lib/presentation/components/AuthHeader.d.ts +11 -0
  59. package/lib/presentation/components/AuthHeader.js +38 -0
  60. package/lib/presentation/components/AuthLegalLinks.d.ts +28 -0
  61. package/lib/presentation/components/AuthLegalLinks.js +54 -0
  62. package/lib/presentation/components/AuthLink.d.ts +13 -0
  63. package/lib/presentation/components/AuthLink.js +27 -0
  64. package/lib/presentation/components/LoginForm.d.ts +10 -0
  65. package/lib/presentation/components/LoginForm.js +27 -0
  66. package/lib/presentation/components/PasswordMatchIndicator.d.ts +9 -0
  67. package/lib/presentation/components/PasswordMatchIndicator.js +30 -0
  68. package/lib/presentation/components/PasswordStrengthIndicator.d.ts +11 -0
  69. package/lib/presentation/components/PasswordStrengthIndicator.js +60 -0
  70. package/lib/presentation/components/RegisterForm.d.ts +14 -0
  71. package/lib/presentation/components/RegisterForm.js +30 -0
  72. package/lib/presentation/hooks/useAuth.d.ts +44 -0
  73. package/lib/presentation/hooks/useAuth.js +38 -0
  74. package/lib/presentation/hooks/useAuthActions.d.ts +15 -0
  75. package/lib/presentation/hooks/useAuthActions.js +162 -0
  76. package/lib/presentation/hooks/useAuthState.d.ts +19 -0
  77. package/lib/presentation/hooks/useAuthState.js +79 -0
  78. package/lib/presentation/hooks/useLoginForm.d.ts +21 -0
  79. package/lib/presentation/hooks/useLoginForm.js +131 -0
  80. package/lib/presentation/hooks/useRegisterForm.d.ts +31 -0
  81. package/lib/presentation/hooks/useRegisterForm.js +136 -0
  82. package/lib/presentation/navigation/AuthNavigator.d.ts +28 -0
  83. package/lib/presentation/navigation/AuthNavigator.js +37 -0
  84. package/lib/presentation/screens/LoginScreen.d.ts +6 -0
  85. package/lib/presentation/screens/LoginScreen.js +15 -0
  86. package/lib/presentation/screens/RegisterScreen.d.ts +12 -0
  87. package/lib/presentation/screens/RegisterScreen.js +15 -0
  88. package/lib/presentation/utils/getAuthErrorMessage.d.ts +8 -0
  89. package/lib/presentation/utils/getAuthErrorMessage.js +69 -0
  90. package/package.json +12 -4
  91. package/src/__tests__/services/AuthCoreService.test.ts +247 -0
  92. package/src/__tests__/services/AuthPackage.test.ts +226 -0
  93. package/src/__tests__/services/GuestModeService.test.ts +194 -0
  94. package/src/__tests__/utils/AuthValidation.test.ts +270 -0
  95. package/src/application/ports/IAuthProvider.ts +0 -0
  96. package/src/application/ports/IAuthService.ts +0 -0
  97. package/src/domain/entities/AuthUser.ts +0 -0
  98. package/src/domain/errors/AuthError.ts +0 -0
  99. package/src/domain/value-objects/AuthConfig.ts +0 -0
  100. package/src/index.ts +0 -0
  101. package/src/infrastructure/adapters/StorageProviderAdapter.ts +73 -0
  102. package/src/infrastructure/adapters/UIProviderAdapter.ts +39 -0
  103. package/src/infrastructure/providers/FirebaseAuthProvider.ts +10 -2
  104. package/src/infrastructure/services/AuthCoreService.ts +138 -0
  105. package/src/infrastructure/services/AuthEventService.ts +115 -0
  106. package/src/infrastructure/services/AuthPackage.ts +148 -0
  107. package/src/infrastructure/services/AuthService.ts +62 -128
  108. package/src/infrastructure/services/GuestModeService.ts +86 -0
  109. package/src/infrastructure/storage/GuestModeStorage.ts +40 -14
  110. package/src/infrastructure/utils/AuthErrorMapper.ts +7 -3
  111. package/src/infrastructure/utils/AuthEventEmitter.ts +0 -0
  112. package/src/infrastructure/utils/AuthValidation.ts +47 -17
  113. package/src/infrastructure/utils/UserMapper.ts +0 -0
  114. package/src/presentation/components/AuthContainer.tsx +0 -0
  115. package/src/presentation/components/AuthDivider.tsx +0 -0
  116. package/src/presentation/components/AuthErrorDisplay.tsx +0 -0
  117. package/src/presentation/components/AuthFormCard.tsx +0 -0
  118. package/src/presentation/components/AuthGradientBackground.tsx +0 -0
  119. package/src/presentation/components/AuthHeader.tsx +0 -0
  120. package/src/presentation/components/AuthLegalLinks.tsx +0 -0
  121. package/src/presentation/components/AuthLink.tsx +0 -0
  122. package/src/presentation/components/LoginForm.tsx +0 -0
  123. package/src/presentation/components/PasswordMatchIndicator.tsx +2 -2
  124. package/src/presentation/components/PasswordStrengthIndicator.tsx +0 -0
  125. package/src/presentation/components/RegisterForm.tsx +0 -0
  126. package/src/presentation/hooks/useAuth.ts +0 -0
  127. package/src/presentation/hooks/useAuthActions.ts +8 -11
  128. package/src/presentation/hooks/useAuthState.ts +10 -0
  129. package/src/presentation/hooks/useLoginForm.ts +0 -0
  130. package/src/presentation/hooks/useRegisterForm.ts +16 -17
  131. package/src/presentation/navigation/AuthNavigator.tsx +2 -2
  132. package/src/presentation/screens/LoginScreen.tsx +3 -6
  133. package/src/presentation/screens/RegisterScreen.tsx +3 -6
  134. package/src/presentation/utils/getAuthErrorMessage.ts +0 -0
  135. package/src/types/external.d.ts +68 -0
  136. package/LICENSE +0 -22
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Guest Mode Service
3
+ * Handles guest mode functionality
4
+ */
5
+
6
+ import type { IAuthProvider } from "../../application/ports/IAuthProvider";
7
+ import type { AuthUser } from "../../domain/entities/AuthUser";
8
+ import { emitGuestModeEnabled } from "../utils/AuthEventEmitter";
9
+
10
+ export interface IStorageProvider {
11
+ get(key: string): Promise<string | null>;
12
+ set(key: string, value: string): Promise<void>;
13
+ remove(key: string): Promise<void>;
14
+ }
15
+
16
+ export class GuestModeService {
17
+ private isGuestMode: boolean = false;
18
+ private storageKey: string;
19
+
20
+ constructor(storageKey: string = "@auth_guest_mode") {
21
+ this.storageKey = storageKey;
22
+ }
23
+
24
+ async load(storageProvider: IStorageProvider): Promise<boolean> {
25
+ try {
26
+ const value = await storageProvider.get(this.storageKey);
27
+ this.isGuestMode = value === "true";
28
+ return this.isGuestMode;
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+
34
+ async save(storageProvider: IStorageProvider): Promise<void> {
35
+ try {
36
+ await storageProvider.set(this.storageKey, this.isGuestMode.toString());
37
+ } catch {
38
+ // Silently fail storage operations
39
+ }
40
+ }
41
+
42
+ async clear(storageProvider: IStorageProvider): Promise<void> {
43
+ try {
44
+ await storageProvider.remove(this.storageKey);
45
+ } catch {
46
+ // Silently fail storage operations
47
+ }
48
+ this.isGuestMode = false;
49
+ }
50
+
51
+ async enable(storageProvider: IStorageProvider, provider?: IAuthProvider): Promise<void> {
52
+ // Sign out from provider if logged in
53
+ if (provider?.getCurrentUser()) {
54
+ try {
55
+ await provider.signOut();
56
+ } catch {
57
+ // Ignore sign out errors when switching to guest mode
58
+ }
59
+ }
60
+
61
+ this.isGuestMode = true;
62
+ await this.save(storageProvider);
63
+ emitGuestModeEnabled();
64
+ }
65
+
66
+ getIsGuestMode(): boolean {
67
+ return this.isGuestMode;
68
+ }
69
+
70
+ setGuestMode(enabled: boolean): void {
71
+ this.isGuestMode = enabled;
72
+ }
73
+
74
+ wrapAuthStateCallback(
75
+ callback: (user: AuthUser | null) => void
76
+ ): (user: AuthUser | null) => void {
77
+ return (user: AuthUser | null) => {
78
+ // Don't update if in guest mode
79
+ if (!this.isGuestMode) {
80
+ callback(user);
81
+ } else {
82
+ callback(null);
83
+ }
84
+ };
85
+ }
86
+ }
@@ -3,18 +3,27 @@
3
3
  * Single Responsibility: Manage guest mode persistence
4
4
  */
5
5
 
6
- import { storageRepository, unwrap } from "@umituz/react-native-storage";
7
-
8
- const GUEST_MODE_KEY = "@auth_guest_mode";
6
+ import type { IStorageProvider } from "../services/GuestModeService";
7
+ import { getAuthPackage } from "../services/AuthPackage";
9
8
 
10
9
  /**
11
10
  * Load guest mode from storage
12
11
  */
13
- export async function loadGuestMode(): Promise<boolean> {
12
+ export async function loadGuestMode(storageKey?: string): Promise<boolean> {
14
13
  try {
15
- const result = await storageRepository.getString(GUEST_MODE_KEY, "false");
16
- const guestModeValue = unwrap(result, "false");
17
- return guestModeValue === "true";
14
+ const packageConfig = getAuthPackage()?.getConfig();
15
+ const key = storageKey ?? packageConfig?.storageKeys.guestMode ?? "@auth_guest_mode";
16
+
17
+ const storageProvider = getAuthPackage()?.getStorageProvider();
18
+ if (!storageProvider) {
19
+ if (__DEV__) {
20
+ console.warn("[GuestModeStorage] No storage provider available");
21
+ }
22
+ return false;
23
+ }
24
+
25
+ const value = await storageProvider.get(key);
26
+ return value === "true";
18
27
  } catch {
19
28
  return false;
20
29
  }
@@ -23,19 +32,28 @@ export async function loadGuestMode(): Promise<boolean> {
23
32
  /**
24
33
  * Save guest mode to storage
25
34
  */
26
- export async function saveGuestMode(isGuest: boolean): Promise<void> {
35
+ export async function saveGuestMode(isGuest: boolean, storageKey?: string): Promise<void> {
27
36
  try {
37
+ const packageConfig = getAuthPackage()?.getConfig();
38
+ const key = storageKey ?? packageConfig?.storageKeys.guestMode ?? "@auth_guest_mode";
39
+
40
+ const storageProvider = getAuthPackage()?.getStorageProvider();
41
+ if (!storageProvider) {
42
+ if (__DEV__) {
43
+ console.warn("[GuestModeStorage] No storage provider available");
44
+ }
45
+ return;
46
+ }
47
+
28
48
  if (isGuest) {
29
- await storageRepository.setString(GUEST_MODE_KEY, "true");
30
- /* eslint-disable-next-line no-console */
49
+ await storageProvider.set(key, "true");
31
50
  if (__DEV__) {
32
51
  console.log("[GuestModeStorage] Guest mode persisted to storage");
33
52
  }
34
53
  } else {
35
- await storageRepository.removeItem(GUEST_MODE_KEY);
54
+ await storageProvider.remove(key);
36
55
  }
37
56
  } catch (error) {
38
- /* eslint-disable-next-line no-console */
39
57
  if (__DEV__) {
40
58
  console.warn("[GuestModeStorage] Failed to persist guest mode:", error);
41
59
  }
@@ -45,9 +63,17 @@ export async function saveGuestMode(isGuest: boolean): Promise<void> {
45
63
  /**
46
64
  * Clear guest mode from storage
47
65
  */
48
- export async function clearGuestMode(): Promise<void> {
66
+ export async function clearGuestMode(storageKey?: string): Promise<void> {
49
67
  try {
50
- await storageRepository.removeItem(GUEST_MODE_KEY);
68
+ const packageConfig = getAuthPackage()?.getConfig();
69
+ const key = storageKey ?? packageConfig?.storageKeys.guestMode ?? "@auth_guest_mode";
70
+
71
+ const storageProvider = getAuthPackage()?.getStorageProvider();
72
+ if (!storageProvider) {
73
+ return;
74
+ }
75
+
76
+ await storageProvider.remove(key);
51
77
  } catch {
52
78
  // Ignore storage errors
53
79
  }
@@ -18,9 +18,13 @@ import {
18
18
  * Map Firebase Auth errors to domain errors
19
19
  */
20
20
  export function mapFirebaseAuthError(error: unknown): Error {
21
- const errorObj = error as { code?: string; message?: string } | undefined;
22
- const code = errorObj?.code || "";
23
- const message = errorObj?.message || "Authentication failed";
21
+ if (!error || typeof error !== 'object') {
22
+ return new AuthError("Authentication failed", "AUTH_UNKNOWN_ERROR");
23
+ }
24
+
25
+ const errorObj = error as { code?: string; message?: string };
26
+ const code = errorObj.code || "";
27
+ const message = errorObj.message || "Authentication failed";
24
28
 
25
29
  switch (code) {
26
30
  case "auth/email-already-in-use":
File without changes
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { PasswordConfig } from "../../domain/value-objects/AuthConfig";
7
+ import { getAuthPackage } from "../services/AuthPackage";
7
8
 
8
9
  export interface ValidationResult {
9
10
  isValid: boolean;
@@ -22,11 +23,35 @@ export interface PasswordRequirements {
22
23
  hasSpecialChar: boolean;
23
24
  }
24
25
 
25
- const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
26
- const UPPERCASE_REGEX = /[A-Z]/;
27
- const LOWERCASE_REGEX = /[a-z]/;
28
- const NUMBER_REGEX = /[0-9]/;
29
- const SPECIAL_CHAR_REGEX = /[!@#$%^&*(),.?":{}|<>]/;
26
+ export interface ValidationConfig {
27
+ emailRegex: RegExp;
28
+ uppercaseRegex: RegExp;
29
+ lowercaseRegex: RegExp;
30
+ numberRegex: RegExp;
31
+ specialCharRegex: RegExp;
32
+ displayNameMinLength: number;
33
+ }
34
+
35
+ const DEFAULT_VALIDATION_CONFIG: ValidationConfig = {
36
+ emailRegex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
37
+ uppercaseRegex: /[A-Z]/,
38
+ lowercaseRegex: /[a-z]/,
39
+ numberRegex: /[0-9]/,
40
+ specialCharRegex: /[!@#$%^&*(),.?":{}|<>]/,
41
+ displayNameMinLength: 2,
42
+ };
43
+
44
+ function getValidationConfig(): ValidationConfig {
45
+ const packageConfig = getAuthPackage()?.getConfig();
46
+ return {
47
+ emailRegex: packageConfig?.validation.emailRegex || DEFAULT_VALIDATION_CONFIG.emailRegex,
48
+ uppercaseRegex: DEFAULT_VALIDATION_CONFIG.uppercaseRegex,
49
+ lowercaseRegex: DEFAULT_VALIDATION_CONFIG.lowercaseRegex,
50
+ numberRegex: DEFAULT_VALIDATION_CONFIG.numberRegex,
51
+ specialCharRegex: DEFAULT_VALIDATION_CONFIG.specialCharRegex,
52
+ displayNameMinLength: DEFAULT_VALIDATION_CONFIG.displayNameMinLength,
53
+ };
54
+ }
30
55
 
31
56
  /**
32
57
  * Validate email format
@@ -36,7 +61,8 @@ export function validateEmail(email: string): ValidationResult {
36
61
  return { isValid: false, error: "Email is required" };
37
62
  }
38
63
 
39
- if (!EMAIL_REGEX.test(email.trim())) {
64
+ const config = getValidationConfig();
65
+ if (!config.emailRegex.test(email.trim())) {
40
66
  return { isValid: false, error: "Please enter a valid email address" };
41
67
  }
42
68
 
@@ -63,13 +89,14 @@ export function validatePasswordForRegister(
63
89
  password: string,
64
90
  config: PasswordConfig
65
91
  ): PasswordStrengthResult {
92
+ const validationConfig = getValidationConfig();
66
93
  const requirements: PasswordRequirements = {
67
94
  hasMinLength: password.length >= config.minLength,
68
- hasUppercase: !config.requireUppercase || UPPERCASE_REGEX.test(password),
69
- hasLowercase: !config.requireLowercase || LOWERCASE_REGEX.test(password),
70
- hasNumber: !config.requireNumber || NUMBER_REGEX.test(password),
95
+ hasUppercase: !config.requireUppercase || validationConfig.uppercaseRegex.test(password),
96
+ hasLowercase: !config.requireLowercase || validationConfig.lowercaseRegex.test(password),
97
+ hasNumber: !config.requireNumber || validationConfig.numberRegex.test(password),
71
98
  hasSpecialChar:
72
- !config.requireSpecialChar || SPECIAL_CHAR_REGEX.test(password),
99
+ !config.requireSpecialChar || validationConfig.specialCharRegex.test(password),
73
100
  };
74
101
 
75
102
  if (!password || password.length === 0) {
@@ -88,7 +115,7 @@ export function validatePasswordForRegister(
88
115
  };
89
116
  }
90
117
 
91
- if (config.requireUppercase && !UPPERCASE_REGEX.test(password)) {
118
+ if (config.requireUppercase && !validationConfig.uppercaseRegex.test(password)) {
92
119
  return {
93
120
  isValid: false,
94
121
  error: "Password must contain at least one uppercase letter",
@@ -96,7 +123,7 @@ export function validatePasswordForRegister(
96
123
  };
97
124
  }
98
125
 
99
- if (config.requireLowercase && !LOWERCASE_REGEX.test(password)) {
126
+ if (config.requireLowercase && !validationConfig.lowercaseRegex.test(password)) {
100
127
  return {
101
128
  isValid: false,
102
129
  error: "Password must contain at least one lowercase letter",
@@ -104,7 +131,7 @@ export function validatePasswordForRegister(
104
131
  };
105
132
  }
106
133
 
107
- if (config.requireNumber && !NUMBER_REGEX.test(password)) {
134
+ if (config.requireNumber && !validationConfig.numberRegex.test(password)) {
108
135
  return {
109
136
  isValid: false,
110
137
  error: "Password must contain at least one number",
@@ -112,7 +139,7 @@ export function validatePasswordForRegister(
112
139
  };
113
140
  }
114
141
 
115
- if (config.requireSpecialChar && !SPECIAL_CHAR_REGEX.test(password)) {
142
+ if (config.requireSpecialChar && !validationConfig.specialCharRegex.test(password)) {
116
143
  return {
117
144
  isValid: false,
118
145
  error: "Password must contain at least one special character",
@@ -146,16 +173,19 @@ export function validatePasswordConfirmation(
146
173
  */
147
174
  export function validateDisplayName(
148
175
  displayName: string,
149
- minLength: number = 2
176
+ minLength?: number
150
177
  ): ValidationResult {
151
178
  if (!displayName || displayName.trim() === "") {
152
179
  return { isValid: false, error: "Name is required" };
153
180
  }
154
181
 
155
- if (displayName.trim().length < minLength) {
182
+ const config = getValidationConfig();
183
+ const actualMinLength = minLength ?? config.displayNameMinLength;
184
+
185
+ if (displayName.trim().length < actualMinLength) {
156
186
  return {
157
187
  isValid: false,
158
- error: `Name must be at least ${minLength} characters`,
188
+ error: `Name must be at least ${actualMinLength} characters`,
159
189
  };
160
190
  }
161
191
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -20,8 +20,8 @@ export const PasswordMatchIndicator: React.FC<PasswordMatchIndicatorProps> = ({
20
20
 
21
21
  const color = isMatch ? tokens.colors.success : tokens.colors.error;
22
22
  const text = isMatch
23
- ? t("auth.passwordsMatch", "Passwords match")
24
- : t("auth.passwordsDontMatch", "Passwords don't match");
23
+ ? t("auth.passwordsMatch", { defaultValue: "Passwords match" })
24
+ : t("auth.passwordsDontMatch", { defaultValue: "Passwords don't match" });
25
25
 
26
26
  return (
27
27
  <View style={styles.container}>
File without changes
File without changes
@@ -40,8 +40,8 @@ export function useAuthActions(
40
40
  if (isGuest) {
41
41
  setIsGuest(false);
42
42
  }
43
- } catch (err: any) {
44
- const errorMessage = err.message || "Sign up failed";
43
+ } catch (err: unknown) {
44
+ const errorMessage = err instanceof Error ? err.message : "Sign up failed";
45
45
  setError(errorMessage);
46
46
  throw err;
47
47
  } finally {
@@ -79,12 +79,8 @@ export function useAuthActions(
79
79
  }
80
80
  setIsGuest(false);
81
81
  }
82
- } catch (err: any) {
83
- /* eslint-disable-next-line no-console */
84
- if (__DEV__) {
85
- console.error("[useAuthActions] Error in signIn:", err);
86
- }
87
- const errorMessage = err.message || "Failed to sign in";
82
+ } catch (err: unknown) {
83
+ const errorMessage = err instanceof Error ? err.message : "Sign in failed";
88
84
  setError(errorMessage);
89
85
  throw err;
90
86
  } finally {
@@ -152,12 +148,13 @@ export function useAuthActions(
152
148
  if (__DEV__) {
153
149
  console.log("[useAuthActions] ✅ isGuest set to true");
154
150
  }
155
- } catch (error) {
156
- /* eslint-disable-next-line no-console */
151
+ } catch (error: unknown) {
152
+ const errorMessage = error instanceof Error ? error.message : "Failed to continue as guest";
153
+ setError(errorMessage);
157
154
  if (__DEV__) {
158
155
  console.error("[useAuthActions] ❌ ERROR in continueAsGuest:", error);
159
156
  console.error("[useAuthActions] Error details:", {
160
- message: error instanceof Error ? error.message : String(error),
157
+ message: errorMessage,
161
158
  stack: error instanceof Error ? error.stack : undefined,
162
159
  });
163
160
  }
@@ -83,9 +83,19 @@ export function useAuthState(): UseAuthStateResult {
83
83
  }
84
84
  );
85
85
 
86
+ const errorSubscription = DeviceEventEmitter.addListener(
87
+ "auth-error",
88
+ (payload: any) => {
89
+ if (payload?.error) {
90
+ setError(payload.error);
91
+ }
92
+ }
93
+ );
94
+
86
95
  return () => {
87
96
  guestSubscription.remove();
88
97
  authSubscription.remove();
98
+ errorSubscription.remove();
89
99
  };
90
100
  }, []);
91
101
 
File without changes
@@ -131,23 +131,22 @@ export function useRegisterForm(): UseRegisterFormResult {
131
131
  setLocalError(null);
132
132
  setFieldErrors({});
133
133
 
134
- const validationResult = batchValidate([
135
- {
136
- field: "email",
137
- validator: () => validateEmail(email.trim()),
138
- },
139
- {
140
- field: "password",
141
- validator: () => validatePasswordForRegister(password, DEFAULT_PASSWORD_CONFIG),
142
- },
143
- {
144
- field: "confirmPassword",
145
- validator: () => validatePasswordConfirmation(password, confirmPassword),
146
- },
147
- ]);
148
-
149
- if (!validationResult.isValid) {
150
- setFieldErrors(validationResult.errors);
134
+ // Manual validation since batchValidate is not available
135
+ const emailResult = validateEmail(email.trim());
136
+ if (!emailResult.isValid) {
137
+ setFieldErrors((prev) => ({ ...prev, email: emailResult.error }));
138
+ return;
139
+ }
140
+
141
+ const passwordResult = validatePasswordForRegister(password, DEFAULT_PASSWORD_CONFIG);
142
+ if (!passwordResult.isValid) {
143
+ setFieldErrors((prev) => ({ ...prev, password: passwordResult.error }));
144
+ return;
145
+ }
146
+
147
+ const confirmResult = validatePasswordConfirmation(password, confirmPassword);
148
+ if (!confirmResult.isValid) {
149
+ setFieldErrors((prev) => ({ ...prev, confirmPassword: confirmResult.error }));
151
150
  return;
152
151
  }
153
152
 
@@ -16,7 +16,7 @@ export type AuthStackParamList = {
16
16
  Register: undefined;
17
17
  };
18
18
 
19
- const AuthStack = createStackNavigator<AuthStackParamList>();
19
+ const AuthStack = createStackNavigator();
20
20
 
21
21
  const SHOW_REGISTER_KEY = "auth_show_register";
22
22
 
@@ -76,7 +76,7 @@ export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
76
76
  >
77
77
  <AuthStack.Screen name="Login" component={LoginScreen} />
78
78
  <AuthStack.Screen name="Register">
79
- {(props) => (
79
+ {(props: any) => (
80
80
  <RegisterScreen
81
81
  {...props}
82
82
  termsUrl={termsUrl}
@@ -13,17 +13,14 @@ import { AuthHeader } from "../components/AuthHeader";
13
13
  import { AuthFormCard } from "../components/AuthFormCard";
14
14
  import { LoginForm } from "../components/LoginForm";
15
15
 
16
- type LoginScreenNavigationProp = StackNavigationProp<
17
- AuthStackParamList,
18
- "Login"
19
- >;
16
+ type LoginScreenNavigationProp = any;
20
17
 
21
18
  export const LoginScreen: React.FC = () => {
22
19
  const { t } = useLocalization();
23
- const navigation = useNavigation<LoginScreenNavigationProp>();
20
+ const navigation = useNavigation();
24
21
 
25
22
  const handleNavigateToRegister = () => {
26
- navigation.navigate("Register");
23
+ navigation.navigate("Register" as any);
27
24
  };
28
25
 
29
26
  return (
@@ -13,10 +13,7 @@ import { AuthHeader } from "../components/AuthHeader";
13
13
  import { AuthFormCard } from "../components/AuthFormCard";
14
14
  import { RegisterForm } from "../components/RegisterForm";
15
15
 
16
- type RegisterScreenNavigationProp = StackNavigationProp<
17
- AuthStackParamList,
18
- "Register"
19
- >;
16
+ type RegisterScreenNavigationProp = any;
20
17
 
21
18
  export interface RegisterScreenProps {
22
19
  termsUrl?: string;
@@ -32,10 +29,10 @@ export const RegisterScreen: React.FC<RegisterScreenProps> = ({
32
29
  onPrivacyPress,
33
30
  }) => {
34
31
  const { t } = useLocalization();
35
- const navigation = useNavigation<RegisterScreenNavigationProp>();
32
+ const navigation = useNavigation();
36
33
 
37
34
  const handleNavigateToLogin = () => {
38
- navigation.navigate("Login");
35
+ navigation.navigate("Login" as any);
39
36
  };
40
37
 
41
38
  return (
File without changes
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Type declarations for external dependencies
3
+ * These are optional dependencies that should be provided by the consuming application
4
+ */
5
+
6
+ declare module '@umituz/react-native-design-system-theme' {
7
+ export function useAppDesignTokens(): any;
8
+ export const defaultTheme: any;
9
+ }
10
+
11
+ declare module '@umituz/react-native-design-system-atoms' {
12
+ export const AtomicInput: any;
13
+ export const AtomicButton: any;
14
+ export const AtomicText: any;
15
+ export const AtomicView: any;
16
+ }
17
+
18
+ declare module '@umituz/react-native-localization' {
19
+ export function useTranslation(): {
20
+ t: (key: string, params?: Record<string, any>) => string;
21
+ };
22
+ export function useLocalization(): {
23
+ t: (key: string, params?: Record<string, any>) => string;
24
+ };
25
+ }
26
+
27
+ declare module '@umituz/react-native-firebase-auth' {
28
+ export function useFirebaseAuth(): any;
29
+ }
30
+
31
+ declare module '@umituz/react-native-validation' {
32
+ export function useValidation(): any;
33
+ export function batchValidate(): any;
34
+ }
35
+
36
+ declare module '@umituz/react-native-storage' {
37
+ export const storageRepository: {
38
+ getString: (key: string, defaultValue?: string) => Promise<{ value: string } | null>;
39
+ setString: (key: string, value: string) => Promise<void>;
40
+ removeItem: (key: string) => Promise<void>;
41
+ };
42
+ export function unwrap(result: any, defaultValue: any): any;
43
+ }
44
+
45
+ declare module 'react-native-safe-area-context' {
46
+ export function useSafeAreaInsets(): {
47
+ top: number;
48
+ bottom: number;
49
+ left: number;
50
+ right: number;
51
+ };
52
+ }
53
+
54
+ declare module 'expo-linear-gradient' {
55
+ import { ComponentType } from 'react';
56
+ export const LinearGradient: ComponentType<any>;
57
+ }
58
+
59
+ declare module '@react-navigation/stack' {
60
+ import { ComponentType } from 'react';
61
+ export const createStackNavigator: any;
62
+ export type StackNavigationProp<any> = any;
63
+ }
64
+
65
+ declare module '@react-navigation/native' {
66
+ export function useNavigation(): any;
67
+ export function useFocusEffect(effect: () => void | (() => void)): void;
68
+ }
package/LICENSE DELETED
@@ -1,22 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Ümit UZ
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-