@umituz/react-native-firebase 1.13.148 → 1.13.150

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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/auth/infrastructure/services/apple-auth.service.ts +10 -2
  3. package/src/auth/infrastructure/services/google-auth.service.ts +10 -2
  4. package/src/auth/infrastructure/services/reauthentication.service.ts +5 -1
  5. package/src/auth/presentation/hooks/shared/auth-hooks.util.ts +60 -0
  6. package/src/auth/presentation/hooks/shared/hook-utils.util.ts +14 -216
  7. package/src/auth/presentation/hooks/shared/safe-state-hooks.util.ts +76 -0
  8. package/src/auth/presentation/hooks/shared/state-hooks.util.ts +97 -0
  9. package/src/domain/utils/async-executor.util.ts +16 -169
  10. package/src/domain/utils/error-handler.util.ts +18 -170
  11. package/src/domain/utils/error-handlers/error-checkers.ts +120 -0
  12. package/src/domain/utils/error-handlers/error-converters.ts +48 -0
  13. package/src/domain/utils/error-handlers/error-messages.ts +18 -0
  14. package/src/domain/utils/executors/advanced-executors.util.ts +59 -0
  15. package/src/domain/utils/executors/basic-executors.util.ts +56 -0
  16. package/src/domain/utils/executors/batch-executors.util.ts +42 -0
  17. package/src/domain/utils/executors/error-converters.util.ts +45 -0
  18. package/src/domain/utils/result/result-creators.ts +49 -0
  19. package/src/domain/utils/result/result-helpers.ts +60 -0
  20. package/src/domain/utils/result/result-types.ts +40 -0
  21. package/src/domain/utils/result.util.ts +28 -127
  22. package/src/domain/utils/validation.util.ts +38 -209
  23. package/src/domain/utils/validators/composite.validator.ts +24 -0
  24. package/src/domain/utils/validators/firebase.validator.ts +45 -0
  25. package/src/domain/utils/validators/generic.validator.ts +59 -0
  26. package/src/domain/utils/validators/string.validator.ts +25 -0
  27. package/src/domain/utils/validators/url.validator.ts +36 -0
  28. package/src/domain/utils/validators/user-input.validator.ts +54 -0
  29. package/src/firestore/infrastructure/middleware/QuotaTrackingMiddleware.ts +10 -3
  30. package/src/firestore/utils/deduplication/timer-manager.util.ts +2 -2
  31. package/src/firestore/utils/pagination.helper.ts +3 -1
  32. package/src/infrastructure/config/FirebaseClient.ts +28 -189
  33. package/src/infrastructure/config/clients/FirebaseClientSingleton.ts +82 -0
  34. package/src/infrastructure/config/services/FirebaseInitializationService.ts +115 -0
  35. package/src/init/createFirebaseInitModule.ts +9 -3
@@ -1,176 +1,23 @@
1
1
  /**
2
2
  * Async Operation Executor Utility
3
- * Centralized async operation execution with error handling
4
- * Eliminates code duplication across services
3
+ * Re-exports all async executors for backward compatibility
4
+ * @deprecated Import from specific executor files instead
5
5
  */
6
6
 
7
- import type { Result, FailureResult } from './result.util';
8
- import { failureResultFromError, successResult } from './result.util';
7
+ // Error Converters
8
+ export type { ErrorConverter } from './executors/error-converters.util';
9
+ export { authErrorConverter, defaultErrorConverter } from './executors/error-converters.util';
9
10
 
10
- /**
11
- * Error converter function type
12
- * Converts unknown errors to ErrorInfo
13
- */
14
- export type ErrorConverter = (error: unknown) => { code: string; message: string };
15
-
16
- /**
17
- * Default error converter for auth operations
18
- */
19
- export function authErrorConverter(error: unknown): { code: string; message: string } {
20
- if (error instanceof Error) {
21
- return {
22
- code: (error as { code?: string }).code ?? 'auth/failed',
23
- message: error.message,
24
- };
25
- }
26
- return {
27
- code: 'auth/failed',
28
- message: typeof error === 'string' ? error : 'Authentication failed',
29
- };
30
- }
31
-
32
- /**
33
- * Default error converter for operations
34
- */
35
- export function defaultErrorConverter(
36
- error: unknown,
37
- defaultCode = 'operation/failed'
38
- ): { code: string; message: string } {
39
- if (error instanceof Error) {
40
- return {
41
- code: (error as { code?: string }).code ?? defaultCode,
42
- message: error.message,
43
- };
44
- }
45
- return {
46
- code: defaultCode,
47
- message: typeof error === 'string' ? error : 'Operation failed',
48
- };
49
- }
50
-
51
- /**
52
- * Execute async operation with error handling
53
- * Returns Result type with success/failure
54
- */
55
- export async function executeOperation<T>(
56
- operation: () => Promise<T>,
57
- errorConverter?: ErrorConverter
58
- ): Promise<Result<T>> {
59
- try {
60
- const data = await operation();
61
- return successResult(data);
62
- } catch (error) {
63
- const converter = errorConverter ?? defaultErrorConverter;
64
- return { success: false, error: converter(error) };
65
- }
66
- }
67
-
68
- /**
69
- * Execute async operation with error handling and default code
70
- */
71
- export async function executeOperationWithCode<T>(
72
- operation: () => Promise<T>,
73
- defaultErrorCode = 'operation/failed'
74
- ): Promise<Result<T>> {
75
- return executeOperation(operation, (error) => defaultErrorConverter(error, defaultErrorCode));
76
- }
77
-
78
- /**
79
- * Execute async void operation
80
- * Useful for operations that don't return data
81
- */
82
- export async function executeVoidOperation(
83
- operation: () => Promise<void>,
84
- errorConverter?: ErrorConverter
85
- ): Promise<Result<void>> {
86
- return executeOperation(operation, errorConverter) as Promise<Result<void>>;
87
- }
88
-
89
- /**
90
- * Execute async operation with auth error handling
91
- */
92
- export async function executeAuthOperation<T>(
93
- operation: () => Promise<T>
94
- ): Promise<Result<T>> {
95
- return executeOperation(operation, authErrorConverter);
96
- }
11
+ // Basic Executors
12
+ export {
13
+ executeOperation,
14
+ executeOperationWithCode,
15
+ executeVoidOperation,
16
+ executeAuthOperation,
17
+ } from './executors/basic-executors.util';
97
18
 
98
- /**
99
- * Execute multiple operations in parallel
100
- * Returns success only if all operations succeed
101
- */
102
- export async function executeAll<T>(
103
- ...operations: (() => Promise<Result<T>>)[]
104
- ): Promise<Result<T[]>> {
105
- try {
106
- const results = await Promise.all(operations.map((op) => op()));
107
- const failures = results.filter((r) => !r.success);
108
- if (failures.length > 0) {
109
- return failures[0] as FailureResult;
110
- }
111
- const data = results.map((r) => (r as { success: true; data: T }).data);
112
- return successResult(data);
113
- } catch (error) {
114
- return failureResultFromError(error);
115
- }
116
- }
19
+ // Batch Executors
20
+ export { executeAll, executeSequence } from './executors/batch-executors.util';
117
21
 
118
- /**
119
- * Execute operations in sequence, stopping at first failure
120
- */
121
- export async function executeSequence<T>(
122
- ...operations: (() => Promise<Result<T>>)[]
123
- ): Promise<Result<void>> {
124
- for (const operation of operations) {
125
- const result = await operation();
126
- if (!result.success) {
127
- return result as Result<void>;
128
- }
129
- }
130
- return successResult();
131
- }
132
-
133
- /**
134
- * Execute operation with retry
135
- */
136
- export async function executeWithRetry<T>(
137
- operation: () => Promise<T>,
138
- maxRetries = 3,
139
- delayMs = 1000
140
- ): Promise<Result<T>> {
141
- let lastError: unknown;
142
- for (let i = 0; i <= maxRetries; i++) {
143
- try {
144
- const data = await operation();
145
- return successResult(data);
146
- } catch (error) {
147
- lastError = error;
148
- if (i < maxRetries) {
149
- await new Promise((resolve) => setTimeout(resolve, delayMs * (i + 1)));
150
- }
151
- }
152
- }
153
- return failureResultFromError(lastError);
154
- }
155
-
156
- /**
157
- * Execute operation with timeout
158
- */
159
- export async function executeWithTimeout<T>(
160
- operation: () => Promise<T>,
161
- timeoutMs: number
162
- ): Promise<Result<T>> {
163
- return Promise.race([
164
- executeOperation(operation),
165
- new Promise<Result<T>>((resolve) =>
166
- setTimeout(
167
- () =>
168
- resolve({
169
- success: false,
170
- error: { code: 'timeout', message: `Operation timed out after ${timeoutMs}ms` },
171
- }),
172
- timeoutMs
173
- )
174
- ),
175
- ]);
176
- }
22
+ // Advanced Executors
23
+ export { executeWithRetry, executeWithTimeout } from './executors/advanced-executors.util';
@@ -1,178 +1,26 @@
1
1
  /**
2
2
  * Error Handler Utility
3
- * Centralized error handling utilities for Firebase operations
3
+ * Re-exports all error handling utilities for backward compatibility
4
+ * @deprecated Import from specific error-handler files instead
4
5
  */
5
6
 
6
- import { hasCodeProperty, hasMessageProperty, hasCodeAndMessageProperties } from './type-guards.util';
7
+ // Error Converters
8
+ export type { ErrorInfo } from './error-handlers/error-converters';
9
+ export { toErrorInfo, toAuthErrorInfo } from './error-handlers/error-converters';
7
10
 
8
- /**
9
- * Standard error structure with code and message
10
- */
11
- export interface ErrorInfo {
12
- code: string;
13
- message: string;
14
- }
15
-
16
- /**
17
- * Quota error codes
18
- */
19
- const QUOTA_ERROR_CODES = [
20
- 'resource-exhausted',
21
- 'quota-exceeded',
22
- 'RESOURCE_EXHAUSTED',
23
- ];
24
-
25
- /**
26
- * Quota error message patterns
27
- */
28
- const QUOTA_ERROR_MESSAGES = [
29
- 'quota exceeded',
30
- 'quota limit',
31
- 'daily limit',
32
- 'resource exhausted',
33
- 'too many requests',
34
- ];
35
-
36
- /**
37
- * Retryable error codes
38
- */
39
- const RETRYABLE_ERROR_CODES = ['unavailable', 'deadline-exceeded', 'aborted'];
40
-
41
- /**
42
- * Convert unknown error to standard error info
43
- * Handles Error objects, strings, and unknown types
44
- */
45
- export function toErrorInfo(error: unknown): ErrorInfo {
46
- if (error instanceof Error) {
47
- return {
48
- code: hasCodeProperty(error) ? error.code : 'unknown',
49
- message: error.message,
50
- };
51
- }
52
- return {
53
- code: 'unknown',
54
- message: typeof error === 'string' ? error : 'Unknown error',
55
- };
56
- }
57
-
58
- /**
59
- * Convert unknown error to auth error info
60
- * Auth-specific error codes are prefixed with 'auth/'
61
- */
62
- export function toAuthErrorInfo(error: unknown): ErrorInfo {
63
- if (error instanceof Error) {
64
- return {
65
- code: hasCodeProperty(error) && error.code ? error.code : 'auth/failed',
66
- message: error.message,
67
- };
68
- }
69
- return {
70
- code: 'auth/failed',
71
- message: typeof error === 'string' ? error : 'Unknown error',
72
- };
73
- }
74
-
75
- /**
76
- * Check if error info has a specific error code
77
- */
78
- export function hasErrorCode(error: ErrorInfo, code: string): boolean {
79
- return error.code === code;
80
- }
81
-
82
- /**
83
- * Check if error is a cancelled/auth cancelled error
84
- */
85
- export function isCancelledError(error: ErrorInfo): boolean {
86
- return (
87
- error.code === 'auth/cancelled' ||
88
- error.message.includes('ERR_CANCELED')
89
- );
90
- }
91
-
92
- /**
93
- * Check if error info is a quota error
94
- */
95
- export function isQuotaErrorInfo(error: ErrorInfo): boolean {
96
- return (
97
- error.code === 'quota-exceeded' ||
98
- error.code.includes('quota') ||
99
- error.message.toLowerCase().includes('quota')
100
- );
101
- }
102
-
103
- /**
104
- * Check if error info is a network error
105
- */
106
- export function isNetworkError(error: ErrorInfo): boolean {
107
- return (
108
- error.code.includes('network') ||
109
- error.message.toLowerCase().includes('network')
110
- );
111
- }
112
-
113
- /**
114
- * Check if error info is an authentication error
115
- */
116
- export function isAuthError(error: ErrorInfo): boolean {
117
- return error.code.startsWith('auth/');
118
- }
119
-
120
- /**
121
- * Check if unknown error is a Firestore quota error
122
- * Enhanced type guard with proper error checking
123
- */
124
- export function isQuotaError(error: unknown): boolean {
125
- if (!error || typeof error !== 'object') return false;
126
-
127
- if (hasCodeProperty(error)) {
128
- const code = error.code;
129
- return QUOTA_ERROR_CODES.some(
130
- (c) => code === c || code.endsWith(`/${c}`) || code.startsWith(`${c}/`)
131
- );
132
- }
11
+ // Error Checkers
12
+ export {
13
+ hasErrorCode,
14
+ isCancelledError,
15
+ isQuotaErrorInfo,
16
+ isNetworkError,
17
+ isAuthError,
18
+ isQuotaError,
19
+ isRetryableError,
20
+ } from './error-handlers/error-checkers';
133
21
 
134
- if (hasMessageProperty(error)) {
135
- const message = error.message.toLowerCase();
136
- return QUOTA_ERROR_MESSAGES.some((m) => {
137
- const pattern = m.toLowerCase();
138
- return (
139
- message.includes(` ${pattern} `) ||
140
- message.startsWith(`${pattern} `) ||
141
- message.endsWith(` ${pattern}`) ||
142
- message === pattern
143
- );
144
- });
145
- }
146
-
147
- return false;
148
- }
149
-
150
- /**
151
- * Check if error is retryable
152
- */
153
- export function isRetryableError(error: unknown): boolean {
154
- if (!error || typeof error !== 'object') return false;
155
-
156
- if (hasCodeProperty(error)) {
157
- return RETRYABLE_ERROR_CODES.some((code) => error.code.includes(code));
158
- }
159
-
160
- return false;
161
- }
162
-
163
- /**
164
- * Get user-friendly quota error message
165
- */
166
- export function getQuotaErrorMessage(): string {
167
- return 'Daily quota exceeded. Please try again tomorrow or upgrade your plan.';
168
- }
169
-
170
- /**
171
- * Get user-friendly retryable error message
172
- */
173
- export function getRetryableErrorMessage(): string {
174
- return 'Temporary error occurred. Please try again.';
175
- }
22
+ // Error Messages
23
+ export { getQuotaErrorMessage, getRetryableErrorMessage } from './error-handlers/error-messages';
176
24
 
177
25
  // Re-export type guards for convenience
178
- export { hasCodeProperty, hasMessageProperty, hasCodeAndMessageProperties };
26
+ export { hasCodeProperty, hasMessageProperty, hasCodeAndMessageProperties } from './type-guards.util';
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Error Type Checkers
3
+ * Check error types and categories
4
+ */
5
+
6
+ import type { ErrorInfo } from './error-converters';
7
+ import { hasCodeProperty, hasMessageProperty } from '../type-guards.util';
8
+
9
+ /**
10
+ * Quota error codes
11
+ */
12
+ const QUOTA_ERROR_CODES = [
13
+ 'resource-exhausted',
14
+ 'quota-exceeded',
15
+ 'RESOURCE_EXHAUSTED',
16
+ ];
17
+
18
+ /**
19
+ * Quota error message patterns
20
+ */
21
+ const QUOTA_ERROR_MESSAGES = [
22
+ 'quota exceeded',
23
+ 'quota limit',
24
+ 'daily limit',
25
+ 'resource exhausted',
26
+ 'too many requests',
27
+ ];
28
+
29
+ /**
30
+ * Retryable error codes
31
+ */
32
+ const RETRYABLE_ERROR_CODES = ['unavailable', 'deadline-exceeded', 'aborted'];
33
+
34
+ /**
35
+ * Check if error info has a specific error code
36
+ */
37
+ export function hasErrorCode(error: ErrorInfo, code: string): boolean {
38
+ return error.code === code;
39
+ }
40
+
41
+ /**
42
+ * Check if error is a cancelled/auth cancelled error
43
+ */
44
+ export function isCancelledError(error: ErrorInfo): boolean {
45
+ return (
46
+ error.code === 'auth/cancelled' ||
47
+ error.message.includes('ERR_CANCELED')
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Check if error info is a quota error
53
+ */
54
+ export function isQuotaErrorInfo(error: ErrorInfo): boolean {
55
+ return (
56
+ error.code === 'quota-exceeded' ||
57
+ error.code.includes('quota') ||
58
+ error.message.toLowerCase().includes('quota')
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Check if error info is a network error
64
+ */
65
+ export function isNetworkError(error: ErrorInfo): boolean {
66
+ return (
67
+ error.code.includes('network') ||
68
+ error.message.toLowerCase().includes('network')
69
+ );
70
+ }
71
+
72
+ /**
73
+ * Check if error info is an authentication error
74
+ */
75
+ export function isAuthError(error: ErrorInfo): boolean {
76
+ return error.code.startsWith('auth/');
77
+ }
78
+
79
+ /**
80
+ * Check if unknown error is a Firestore quota error
81
+ * Enhanced type guard with proper error checking
82
+ */
83
+ export function isQuotaError(error: unknown): boolean {
84
+ if (!error || typeof error !== 'object') return false;
85
+
86
+ if (hasCodeProperty(error)) {
87
+ const code = error.code;
88
+ return QUOTA_ERROR_CODES.some(
89
+ (c) => code === c || code.endsWith(`/${c}`) || code.startsWith(`${c}/`)
90
+ );
91
+ }
92
+
93
+ if (hasMessageProperty(error)) {
94
+ const message = error.message.toLowerCase();
95
+ return QUOTA_ERROR_MESSAGES.some((m) => {
96
+ const pattern = m.toLowerCase();
97
+ return (
98
+ message.includes(` ${pattern} `) ||
99
+ message.startsWith(`${pattern} `) ||
100
+ message.endsWith(` ${pattern}`) ||
101
+ message === pattern
102
+ );
103
+ });
104
+ }
105
+
106
+ return false;
107
+ }
108
+
109
+ /**
110
+ * Check if error is retryable
111
+ */
112
+ export function isRetryableError(error: unknown): boolean {
113
+ if (!error || typeof error !== 'object') return false;
114
+
115
+ if (hasCodeProperty(error)) {
116
+ return RETRYABLE_ERROR_CODES.some((code) => error.code.includes(code));
117
+ }
118
+
119
+ return false;
120
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Error Converters
3
+ * Convert unknown errors to ErrorInfo
4
+ */
5
+
6
+ import { hasCodeProperty } from '../type-guards.util';
7
+
8
+ /**
9
+ * Standard error structure with code and message
10
+ */
11
+ export interface ErrorInfo {
12
+ code: string;
13
+ message: string;
14
+ }
15
+
16
+ /**
17
+ * Convert unknown error to standard error info
18
+ * Handles Error objects, strings, and unknown types
19
+ */
20
+ export function toErrorInfo(error: unknown): ErrorInfo {
21
+ if (error instanceof Error) {
22
+ return {
23
+ code: hasCodeProperty(error) ? error.code : 'unknown',
24
+ message: error.message,
25
+ };
26
+ }
27
+ return {
28
+ code: 'unknown',
29
+ message: typeof error === 'string' ? error : 'Unknown error',
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Convert unknown error to auth error info
35
+ * Auth-specific error codes are prefixed with 'auth/'
36
+ */
37
+ export function toAuthErrorInfo(error: unknown): ErrorInfo {
38
+ if (error instanceof Error) {
39
+ return {
40
+ code: hasCodeProperty(error) && error.code ? error.code : 'auth/failed',
41
+ message: error.message,
42
+ };
43
+ }
44
+ return {
45
+ code: 'auth/failed',
46
+ message: typeof error === 'string' ? error : 'Unknown error',
47
+ };
48
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Error Messages
3
+ * User-friendly error messages for common error types
4
+ */
5
+
6
+ /**
7
+ * Get user-friendly quota error message
8
+ */
9
+ export function getQuotaErrorMessage(): string {
10
+ return 'Daily quota exceeded. Please try again tomorrow or upgrade your plan.';
11
+ }
12
+
13
+ /**
14
+ * Get user-friendly retryable error message
15
+ */
16
+ export function getRetryableErrorMessage(): string {
17
+ return 'Temporary error occurred. Please try again.';
18
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Advanced Async Executors
3
+ * Retry and timeout support for async operations
4
+ */
5
+
6
+ import type { Result } from '../result.util';
7
+ import { failureResultFromError, successResult } from '../result.util';
8
+ import { executeOperation } from './basic-executors.util';
9
+
10
+ /**
11
+ * Execute operation with retry
12
+ * @param operation - Operation to execute
13
+ * @param maxRetries - Maximum number of retries (default: 3)
14
+ * @param delayMs - Base delay between retries in milliseconds (default: 1000)
15
+ */
16
+ export async function executeWithRetry<T>(
17
+ operation: () => Promise<T>,
18
+ maxRetries = 3,
19
+ delayMs = 1000
20
+ ): Promise<Result<T>> {
21
+ let lastError: unknown;
22
+ for (let i = 0; i <= maxRetries; i++) {
23
+ try {
24
+ const data = await operation();
25
+ return successResult(data);
26
+ } catch (error) {
27
+ lastError = error;
28
+ if (i < maxRetries) {
29
+ // Exponential backoff: delay * (attempt + 1)
30
+ await new Promise((resolve) => setTimeout(resolve, delayMs * (i + 1)));
31
+ }
32
+ }
33
+ }
34
+ return failureResultFromError(lastError);
35
+ }
36
+
37
+ /**
38
+ * Execute operation with timeout
39
+ * @param operation - Operation to execute
40
+ * @param timeoutMs - Timeout in milliseconds
41
+ */
42
+ export async function executeWithTimeout<T>(
43
+ operation: () => Promise<T>,
44
+ timeoutMs: number
45
+ ): Promise<Result<T>> {
46
+ return Promise.race([
47
+ executeOperation(operation),
48
+ new Promise<Result<T>>((resolve) =>
49
+ setTimeout(
50
+ () =>
51
+ resolve({
52
+ success: false,
53
+ error: { code: 'timeout', message: `Operation timed out after ${timeoutMs}ms` },
54
+ }),
55
+ timeoutMs
56
+ )
57
+ ),
58
+ ]);
59
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Basic Async Executors
3
+ * Core async operation execution with error handling
4
+ */
5
+
6
+ import type { Result } from '../result.util';
7
+ import { successResult } from '../result.util';
8
+ import type { ErrorConverter } from './error-converters.util';
9
+ import { authErrorConverter, defaultErrorConverter } from './error-converters.util';
10
+
11
+ /**
12
+ * Execute async operation with error handling
13
+ * Returns Result type with success/failure
14
+ */
15
+ export async function executeOperation<T>(
16
+ operation: () => Promise<T>,
17
+ errorConverter?: ErrorConverter
18
+ ): Promise<Result<T>> {
19
+ try {
20
+ const data = await operation();
21
+ return successResult(data);
22
+ } catch (error) {
23
+ const converter = errorConverter ?? defaultErrorConverter;
24
+ return { success: false, error: converter(error) };
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Execute async operation with error handling and default code
30
+ */
31
+ export async function executeOperationWithCode<T>(
32
+ operation: () => Promise<T>,
33
+ defaultErrorCode = 'operation/failed'
34
+ ): Promise<Result<T>> {
35
+ return executeOperation(operation, (error) => defaultErrorConverter(error, defaultErrorCode));
36
+ }
37
+
38
+ /**
39
+ * Execute async void operation
40
+ * Useful for operations that don't return data
41
+ */
42
+ export async function executeVoidOperation(
43
+ operation: () => Promise<void>,
44
+ errorConverter?: ErrorConverter
45
+ ): Promise<Result<void>> {
46
+ return executeOperation(operation, errorConverter) as Promise<Result<void>>;
47
+ }
48
+
49
+ /**
50
+ * Execute async operation with auth error handling
51
+ */
52
+ export async function executeAuthOperation<T>(
53
+ operation: () => Promise<T>
54
+ ): Promise<Result<T>> {
55
+ return executeOperation(operation, authErrorConverter);
56
+ }