@umituz/react-native-firebase 2.6.3 → 2.6.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 +1 -1
- package/src/application/auth/index.ts +2 -34
- package/src/application/auth/use-cases/index.ts +1 -21
- package/src/domains/account-deletion/domain/index.ts +1 -8
- package/src/domains/account-deletion/index.ts +0 -42
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts +79 -0
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionTypes.ts +0 -1
- package/src/domains/account-deletion/infrastructure/services/account-deletion.service.ts +2 -14
- package/src/domains/auth/index.ts +3 -12
- package/src/domains/auth/infrastructure.ts +11 -0
- package/src/domains/firestore/domain/entities/Collection.ts +0 -2
- package/src/domains/firestore/domain/index.ts +6 -2
- package/src/domains/firestore/domain/value-objects/WhereClause.ts +0 -14
- package/src/domains/firestore/presentation/hooks/useFirestoreMutation.ts +1 -1
- package/src/domains/firestore/presentation/hooks/useFirestoreQuery.ts +1 -1
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts +29 -0
- package/src/application/auth/ports/AuthPort.ts.bak +0 -164
- package/src/application/auth/ports/AuthPort_part_aa +0 -150
- package/src/application/auth/ports/AuthPort_part_ab +0 -14
- package/src/application/auth/use-cases/SignInUseCase.ts.bak +0 -253
- package/src/application/auth/use-cases/SignInUseCaseHelpers.ts +0 -0
- package/src/application/auth/use-cases/SignInUseCaseMain.ts +0 -0
- package/src/application/auth/use-cases/SignInUseCase_part_aa +0 -150
- package/src/application/auth/use-cases/SignInUseCase_part_ab +0 -103
- package/src/application/auth/use-cases/SignOutUseCase.ts.bak +0 -288
- package/src/application/auth/use-cases/SignOutUseCaseCleanup.ts +0 -0
- package/src/application/auth/use-cases/SignOutUseCaseMain.ts +0 -0
- package/src/application/auth/use-cases/SignOutUseCase_part_aa +0 -150
- package/src/application/auth/use-cases/SignOutUseCase_part_ab +0 -138
- package/src/domains/account-deletion/domain/services/UserValidationHelpers.ts.bak +0 -181
- package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_aa +0 -150
- package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_ab +0 -31
- package/src/domains/account-deletion/domain/services/UserValidationService.ts.bak +0 -286
- package/src/domains/account-deletion/domain/services/UserValidationService_part_aa +0 -150
- package/src/domains/account-deletion/domain/services/UserValidationService_part_ab +0 -136
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts.bak +0 -230
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_ab +0 -80
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler.ts.bak +0 -174
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_ab +0 -24
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository.ts.bak +0 -266
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_ab +0 -116
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service.ts.bak +0 -160
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_ab +0 -10
- package/src/domains/auth/infrastructure.ts.bak +0 -156
- package/src/domains/auth/infrastructure_part_aa +0 -150
- package/src/domains/auth/infrastructure_part_ab +0 -6
- package/src/domains/auth/presentation/hooks/GoogleOAuthHelpers.ts +0 -0
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService.ts.bak +0 -247
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_aa +0 -150
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_ab +0 -97
- package/src/domains/auth/presentation/hooks/GoogleOAuthService.ts +0 -0
- package/src/domains/firestore/domain/entities/Collection.ts.bak +0 -288
- package/src/domains/firestore/domain/entities/Collection_part_aa +0 -150
- package/src/domains/firestore/domain/entities/Collection_part_ab +0 -138
- package/src/domains/firestore/domain/entities/Document.ts.bak +0 -233
- package/src/domains/firestore/domain/entities/DocumentHelpers.ts +0 -0
- package/src/domains/firestore/domain/entities/DocumentMain.ts +0 -0
- package/src/domains/firestore/domain/entities/Document_part_aa +0 -150
- package/src/domains/firestore/domain/entities/Document_part_ab +0 -83
- package/src/domains/firestore/domain/services/QueryService.ts.bak +0 -182
- package/src/domains/firestore/domain/services/QueryServiceAnalysis.ts.bak +0 -169
- package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_ab +0 -19
- package/src/domains/firestore/domain/services/QueryServiceHelpers.ts.bak +0 -151
- package/src/domains/firestore/domain/services/QueryServiceHelpers_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryServiceHelpers_part_ab +0 -1
- package/src/domains/firestore/domain/services/QueryService_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryService_part_ab +0 -32
- package/src/domains/firestore/domain/value-objects/QueryOptions.ts.bak +0 -191
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization.ts.bak +0 -207
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_ab +0 -57
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation.ts.bak +0 -182
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_ab +0 -32
- package/src/domains/firestore/domain/value-objects/QueryOptions_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptions_part_ab +0 -41
- package/src/domains/firestore/domain/value-objects/WhereClause.ts.bak +0 -299
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts.bak +0 -207
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_ab +0 -57
- package/src/domains/firestore/domain/value-objects/WhereClause_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/WhereClause_part_ab +0 -149
- package/src/shared/infrastructure/base/ErrorHandler.ts.bak +0 -189
- package/src/shared/infrastructure/base/ErrorHandler_part_aa +0 -150
- package/src/shared/infrastructure/base/ErrorHandler_part_ab +0 -39
- package/src/shared/infrastructure/base/ServiceBase.ts.bak +0 -220
- package/src/shared/infrastructure/base/ServiceBase_part_aa +0 -150
- package/src/shared/infrastructure/base/ServiceBase_part_ab +0 -70
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts.bak +0 -155
- package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_aa +0 -150
- package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_ab +0 -5
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error Handler Base Class
|
|
3
|
-
* Single Responsibility: Centralized error handling and conversion
|
|
4
|
-
*
|
|
5
|
-
* Eliminates try-catch duplication across 9+ files.
|
|
6
|
-
* Provides standardized error-to-ErrorInfo conversion.
|
|
7
|
-
* Integrates with existing Result pattern.
|
|
8
|
-
*
|
|
9
|
-
* Max lines: 150 (enforced for maintainability)
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { ErrorInfo } from '../../domain/utils';
|
|
13
|
-
import { toErrorInfo, successResult, type Result } from '../../domain/utils';
|
|
14
|
-
import { isCancelledError, isQuotaError, isRetryableError } from '../../domain/utils/error-handlers/error-checkers';
|
|
15
|
-
import { ERROR_MESSAGES } from '../../domain/utils/error-handlers/error-messages';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Error handler options
|
|
19
|
-
*/
|
|
20
|
-
export interface ErrorHandlerOptions {
|
|
21
|
-
/** Default error code if none can be extracted */
|
|
22
|
-
defaultErrorCode?: string;
|
|
23
|
-
/** Custom error message mapper */
|
|
24
|
-
errorMapper?: (error: unknown) => string | null;
|
|
25
|
-
/** Enable detailed logging in development */
|
|
26
|
-
enableDevLogging?: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Base class for error handling
|
|
31
|
-
* Provides centralized error conversion and handling
|
|
32
|
-
*/
|
|
33
|
-
export class ErrorHandler {
|
|
34
|
-
private readonly options: ErrorHandlerOptions;
|
|
35
|
-
|
|
36
|
-
constructor(options: ErrorHandlerOptions = {}) {
|
|
37
|
-
this.options = {
|
|
38
|
-
defaultErrorCode: 'unknown/error',
|
|
39
|
-
enableDevLogging: __DEV__,
|
|
40
|
-
...options,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Wrap an async operation with standardized error handling
|
|
46
|
-
* Eliminates try-catch duplication across services
|
|
47
|
-
*/
|
|
48
|
-
async handleAsync<T>(
|
|
49
|
-
operation: () => Promise<T>,
|
|
50
|
-
errorCode: string = this.options.defaultErrorCode || 'unknown/error'
|
|
51
|
-
): Promise<Result<T>> {
|
|
52
|
-
try {
|
|
53
|
-
const result = await operation();
|
|
54
|
-
return successResult(result);
|
|
55
|
-
} catch (error) {
|
|
56
|
-
if (this.options.enableDevLogging) {
|
|
57
|
-
console.error(`[ErrorHandler] Operation failed: ${errorCode}`, error);
|
|
58
|
-
}
|
|
59
|
-
return { success: false, error: toErrorInfo(error, errorCode) };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Wrap a synchronous operation with standardized error handling
|
|
65
|
-
*/
|
|
66
|
-
handle<T>(
|
|
67
|
-
operation: () => T,
|
|
68
|
-
errorCode: string = this.options.defaultErrorCode || 'unknown/error'
|
|
69
|
-
): Result<T> {
|
|
70
|
-
try {
|
|
71
|
-
const result = operation();
|
|
72
|
-
return successResult(result);
|
|
73
|
-
} catch (error) {
|
|
74
|
-
if (this.options.enableDevLogging) {
|
|
75
|
-
console.error(`[ErrorHandler] Operation failed: ${errorCode}`, error);
|
|
76
|
-
}
|
|
77
|
-
return { success: false, error: toErrorInfo(error, errorCode) };
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Convert error to ErrorInfo with optional custom code
|
|
83
|
-
*/
|
|
84
|
-
toErrorInfo(error: unknown, code?: string): ErrorInfo {
|
|
85
|
-
// Try custom error mapper first
|
|
86
|
-
if (this.options.errorMapper) {
|
|
87
|
-
const customMessage = this.options.errorMapper(error);
|
|
88
|
-
if (customMessage) {
|
|
89
|
-
return {
|
|
90
|
-
code: code || this.options.defaultErrorCode || 'unknown/error',
|
|
91
|
-
message: customMessage,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Use standard conversion
|
|
97
|
-
return toErrorInfo(error, code || this.options.defaultErrorCode);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Check if error is a cancelled operation
|
|
102
|
-
*/
|
|
103
|
-
isCancelledError(error: unknown): boolean {
|
|
104
|
-
return isCancelledError(error);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Check if error is a quota error
|
|
109
|
-
*/
|
|
110
|
-
isQuotaError(error: unknown): boolean {
|
|
111
|
-
return isQuotaError(error);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Check if error is retryable
|
|
116
|
-
*/
|
|
117
|
-
isRetryableError(error: unknown): boolean {
|
|
118
|
-
return isRetryableError(error);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Get user-friendly error message
|
|
123
|
-
* Maps error codes to user-friendly messages
|
|
124
|
-
*/
|
|
125
|
-
getUserMessage(error: ErrorInfo): string {
|
|
126
|
-
// Check if it's a known error category
|
|
127
|
-
if (error.code.startsWith('auth/')) {
|
|
128
|
-
return this.getAuthUserMessage(error.code);
|
|
129
|
-
}
|
|
130
|
-
if (error.code.startsWith('firestore/')) {
|
|
131
|
-
return this.getFirestoreUserMessage(error.code);
|
|
132
|
-
}
|
|
133
|
-
if (error.code.startsWith('storage/')) {
|
|
134
|
-
return ERROR_MESSAGES.STORAGE.GENERIC_ERROR;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return error.message || ERROR_MESSAGES.GENERAL.UNKNOWN;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Get user-friendly auth error message
|
|
142
|
-
*/
|
|
143
|
-
private getAuthUserMessage(code: string): string {
|
|
144
|
-
// Map common auth error codes to user-friendly messages
|
|
145
|
-
const authMessages: Record<string, string> = {
|
|
146
|
-
'auth/user-not-found': ERROR_MESSAGES.AUTH.USER_NOT_FOUND,
|
|
147
|
-
'auth/wrong-password': ERROR_MESSAGES.AUTH.INVALID_CREDENTIALS,
|
|
148
|
-
'auth/email-already-in-use': ERROR_MESSAGES.AUTH.EMAIL_ALREADY_IN_USE,
|
|
149
|
-
'auth/invalid-email': ERROR_MESSAGES.AUTH.INVALID_EMAIL,
|
|
150
|
-
'auth/weak-password': ERROR_MESSAGES.AUTH.WEAK_PASSWORD,
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'auth/too-many-requests': ERROR_MESSAGES.AUTH.TOO_MANY_REQUESTS,
|
|
2
|
-
'auth/user-disabled': ERROR_MESSAGES.AUTH.USER_DISABLED,
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
return authMessages[code] || ERROR_MESSAGES.AUTH.GENERIC_ERROR;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Get user-friendly firestore error message
|
|
10
|
-
*/
|
|
11
|
-
private getFirestoreUserMessage(code: string): string {
|
|
12
|
-
const firestoreMessages: Record<string, string> = {
|
|
13
|
-
'firestore/permission-denied': ERROR_MESSAGES.FIRESTORE.PERMISSION_DENIED,
|
|
14
|
-
'firestore/not-found': ERROR_MESSAGES.FIRESTORE.NOT_FOUND,
|
|
15
|
-
'firestore/unavailable': ERROR_MESSAGES.FIRESTORE.UNAVAILABLE,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
return firestoreMessages[code] || ERROR_MESSAGES.FIRESTORE.GENERIC_ERROR;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Create a failure result from error code
|
|
23
|
-
*/
|
|
24
|
-
failureFrom(code: string, message?: string): Result {
|
|
25
|
-
return {
|
|
26
|
-
success: false,
|
|
27
|
-
error: {
|
|
28
|
-
code,
|
|
29
|
-
message: message || ERROR_MESSAGES.GENERAL.UNKNOWN,
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Default error handler instance
|
|
37
|
-
* Can be used across the application
|
|
38
|
-
*/
|
|
39
|
-
export const defaultErrorHandler = new ErrorHandler();
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service Base Class
|
|
3
|
-
* Single Responsibility: Provide common service functionality
|
|
4
|
-
*
|
|
5
|
-
* Base class for all services to eliminate duplication.
|
|
6
|
-
* Integrates error handling and initialization.
|
|
7
|
-
* Reduces service boilerplate by ~50%.
|
|
8
|
-
*
|
|
9
|
-
* Max lines: 150 (enforced for maintainability)
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Result } from '../../domain/utils';
|
|
13
|
-
import { ErrorHandler, type ErrorHandlerOptions } from './ErrorHandler';
|
|
14
|
-
import { successResult } from '../../domain/utils';
|
|
15
|
-
import type { ErrorInfo } from '../../domain/utils';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Service state
|
|
19
|
-
*/
|
|
20
|
-
interface ServiceState {
|
|
21
|
-
isInitialized: boolean;
|
|
22
|
-
initializationError: string | null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Service base options
|
|
27
|
-
*/
|
|
28
|
-
export interface ServiceBaseOptions extends ErrorHandlerOptions {
|
|
29
|
-
/** Service name for logging and error messages */
|
|
30
|
-
serviceName: string;
|
|
31
|
-
/** Auto-initialize on first access */
|
|
32
|
-
autoInitialize?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Base class for all services
|
|
37
|
-
* Provides common initialization, error handling, and state management
|
|
38
|
-
*
|
|
39
|
-
* Usage:
|
|
40
|
-
* ```typescript
|
|
41
|
-
* class MyService extends ServiceBase {
|
|
42
|
-
* constructor() {
|
|
43
|
-
* super({ serviceName: 'MyService' });
|
|
44
|
-
* }
|
|
45
|
-
*
|
|
46
|
-
* async myMethod() {
|
|
47
|
-
* return this.handleAsync(async () => {
|
|
48
|
-
* // Your logic here
|
|
49
|
-
* return result;
|
|
50
|
-
* }, 'my-method/failed');
|
|
51
|
-
* }
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export abstract class ServiceBase {
|
|
56
|
-
protected readonly errorHandler: ErrorHandler;
|
|
57
|
-
protected readonly serviceName: string;
|
|
58
|
-
protected readonly autoInitialize: boolean;
|
|
59
|
-
protected state: ServiceState;
|
|
60
|
-
private initInProgress = false;
|
|
61
|
-
|
|
62
|
-
constructor(options: ServiceBaseOptions) {
|
|
63
|
-
this.serviceName = options.serviceName;
|
|
64
|
-
this.autoInitialize = options.autoInitialize ?? false;
|
|
65
|
-
this.errorHandler = new ErrorHandler({
|
|
66
|
-
...options,
|
|
67
|
-
defaultErrorCode: `${this.serviceName.toLowerCase()}/error`,
|
|
68
|
-
});
|
|
69
|
-
this.state = {
|
|
70
|
-
isInitialized: false,
|
|
71
|
-
initializationError: null,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Initialize the service
|
|
77
|
-
* Override this method to provide custom initialization logic
|
|
78
|
-
*/
|
|
79
|
-
protected async initialize(): Promise<Result<void>> {
|
|
80
|
-
// Override in subclasses
|
|
81
|
-
this.state.isInitialized = true;
|
|
82
|
-
return successResult();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Ensure service is initialized before operation
|
|
87
|
-
* Automatically initializes if autoInitialize is enabled
|
|
88
|
-
*/
|
|
89
|
-
protected async ensureInitialized(): Promise<Result<void>> {
|
|
90
|
-
if (this.state.isInitialized) {
|
|
91
|
-
return successResult();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (this.state.initializationError) {
|
|
95
|
-
return {
|
|
96
|
-
success: false,
|
|
97
|
-
error: {
|
|
98
|
-
code: `${this.serviceName.toLowerCase()}/initialization-failed`,
|
|
99
|
-
message: this.state.initializationError,
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (this.initInProgress) {
|
|
105
|
-
return {
|
|
106
|
-
success: false,
|
|
107
|
-
error: {
|
|
108
|
-
code: `${this.serviceName.toLowerCase()}/initialization-in-progress`,
|
|
109
|
-
message: 'Service initialization is in progress',
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!this.autoInitialize) {
|
|
115
|
-
return {
|
|
116
|
-
success: false,
|
|
117
|
-
error: {
|
|
118
|
-
code: `${this.serviceName.toLowerCase()}/not-initialized`,
|
|
119
|
-
message: 'Service is not initialized. Call initialize() first.',
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
this.initInProgress = true;
|
|
125
|
-
try {
|
|
126
|
-
const result = await this.initialize();
|
|
127
|
-
if (!result.success) {
|
|
128
|
-
this.state.initializationError = result.error?.message || 'Initialization failed';
|
|
129
|
-
return result;
|
|
130
|
-
}
|
|
131
|
-
this.state.isInitialized = true;
|
|
132
|
-
return successResult();
|
|
133
|
-
} finally {
|
|
134
|
-
this.initInProgress = false;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Wrap async operation with error handling and initialization check
|
|
140
|
-
*/
|
|
141
|
-
protected async execute<T>(
|
|
142
|
-
operation: () => Promise<T>,
|
|
143
|
-
errorCode?: string
|
|
144
|
-
): Promise<Result<T>> {
|
|
145
|
-
const initResult = await this.ensureInitialized();
|
|
146
|
-
if (!initResult.success) {
|
|
147
|
-
return {
|
|
148
|
-
success: false,
|
|
149
|
-
error: initResult.error,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return this.errorHandler.handleAsync(operation, errorCode);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Wrap sync operation with error handling
|
|
158
|
-
*/
|
|
159
|
-
protected executeSync<T>(operation: () => T, errorCode?: string): Result<T> {
|
|
160
|
-
return this.errorHandler.handle(operation, errorCode);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Check if service is initialized
|
|
165
|
-
*/
|
|
166
|
-
isInitialized(): boolean {
|
|
167
|
-
return this.state.isInitialized;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Get initialization error if any
|
|
172
|
-
*/
|
|
173
|
-
getInitializationError(): string | null {
|
|
174
|
-
return this.state.initializationError;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Reset service state
|
|
179
|
-
* Override to add custom cleanup logic
|
|
180
|
-
*/
|
|
181
|
-
reset(): void {
|
|
182
|
-
this.state = {
|
|
183
|
-
isInitialized: false,
|
|
184
|
-
initializationError: null,
|
|
185
|
-
};
|
|
186
|
-
this.initInProgress = false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Get service name
|
|
191
|
-
*/
|
|
192
|
-
getServiceName(): string {
|
|
193
|
-
return this.serviceName;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Log in development mode
|
|
198
|
-
*/
|
|
199
|
-
protected log(message: string, ...args: unknown[]): void {
|
|
200
|
-
if (__DEV__) {
|
|
201
|
-
console.log(`[${this.serviceName}] ${message}`, ...args);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Log error in development mode
|
|
207
|
-
*/
|
|
208
|
-
protected logError(message: string, error?: unknown): void {
|
|
209
|
-
if (__DEV__) {
|
|
210
|
-
console.error(`[${this.serviceName}] ${message}`, error);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Create a failure result
|
|
216
|
-
*/
|
|
217
|
-
protected failure(code: string, message?: string): Result {
|
|
218
|
-
return this.errorHandler.failureFrom(code, message);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service Base Class
|
|
3
|
-
* Single Responsibility: Provide common service functionality
|
|
4
|
-
*
|
|
5
|
-
* Base class for all services to eliminate duplication.
|
|
6
|
-
* Integrates error handling and initialization.
|
|
7
|
-
* Reduces service boilerplate by ~50%.
|
|
8
|
-
*
|
|
9
|
-
* Max lines: 150 (enforced for maintainability)
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Result } from '../../domain/utils';
|
|
13
|
-
import { ErrorHandler, type ErrorHandlerOptions } from './ErrorHandler';
|
|
14
|
-
import { successResult } from '../../domain/utils';
|
|
15
|
-
import type { ErrorInfo } from '../../domain/utils';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Service state
|
|
19
|
-
*/
|
|
20
|
-
interface ServiceState {
|
|
21
|
-
isInitialized: boolean;
|
|
22
|
-
initializationError: string | null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Service base options
|
|
27
|
-
*/
|
|
28
|
-
export interface ServiceBaseOptions extends ErrorHandlerOptions {
|
|
29
|
-
/** Service name for logging and error messages */
|
|
30
|
-
serviceName: string;
|
|
31
|
-
/** Auto-initialize on first access */
|
|
32
|
-
autoInitialize?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Base class for all services
|
|
37
|
-
* Provides common initialization, error handling, and state management
|
|
38
|
-
*
|
|
39
|
-
* Usage:
|
|
40
|
-
* ```typescript
|
|
41
|
-
* class MyService extends ServiceBase {
|
|
42
|
-
* constructor() {
|
|
43
|
-
* super({ serviceName: 'MyService' });
|
|
44
|
-
* }
|
|
45
|
-
*
|
|
46
|
-
* async myMethod() {
|
|
47
|
-
* return this.handleAsync(async () => {
|
|
48
|
-
* // Your logic here
|
|
49
|
-
* return result;
|
|
50
|
-
* }, 'my-method/failed');
|
|
51
|
-
* }
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export abstract class ServiceBase {
|
|
56
|
-
protected readonly errorHandler: ErrorHandler;
|
|
57
|
-
protected readonly serviceName: string;
|
|
58
|
-
protected readonly autoInitialize: boolean;
|
|
59
|
-
protected state: ServiceState;
|
|
60
|
-
private initInProgress = false;
|
|
61
|
-
|
|
62
|
-
constructor(options: ServiceBaseOptions) {
|
|
63
|
-
this.serviceName = options.serviceName;
|
|
64
|
-
this.autoInitialize = options.autoInitialize ?? false;
|
|
65
|
-
this.errorHandler = new ErrorHandler({
|
|
66
|
-
...options,
|
|
67
|
-
defaultErrorCode: `${this.serviceName.toLowerCase()}/error`,
|
|
68
|
-
});
|
|
69
|
-
this.state = {
|
|
70
|
-
isInitialized: false,
|
|
71
|
-
initializationError: null,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Initialize the service
|
|
77
|
-
* Override this method to provide custom initialization logic
|
|
78
|
-
*/
|
|
79
|
-
protected async initialize(): Promise<Result<void>> {
|
|
80
|
-
// Override in subclasses
|
|
81
|
-
this.state.isInitialized = true;
|
|
82
|
-
return successResult();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Ensure service is initialized before operation
|
|
87
|
-
* Automatically initializes if autoInitialize is enabled
|
|
88
|
-
*/
|
|
89
|
-
protected async ensureInitialized(): Promise<Result<void>> {
|
|
90
|
-
if (this.state.isInitialized) {
|
|
91
|
-
return successResult();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (this.state.initializationError) {
|
|
95
|
-
return {
|
|
96
|
-
success: false,
|
|
97
|
-
error: {
|
|
98
|
-
code: `${this.serviceName.toLowerCase()}/initialization-failed`,
|
|
99
|
-
message: this.state.initializationError,
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (this.initInProgress) {
|
|
105
|
-
return {
|
|
106
|
-
success: false,
|
|
107
|
-
error: {
|
|
108
|
-
code: `${this.serviceName.toLowerCase()}/initialization-in-progress`,
|
|
109
|
-
message: 'Service initialization is in progress',
|
|
110
|
-
},
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!this.autoInitialize) {
|
|
115
|
-
return {
|
|
116
|
-
success: false,
|
|
117
|
-
error: {
|
|
118
|
-
code: `${this.serviceName.toLowerCase()}/not-initialized`,
|
|
119
|
-
message: 'Service is not initialized. Call initialize() first.',
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
this.initInProgress = true;
|
|
125
|
-
try {
|
|
126
|
-
const result = await this.initialize();
|
|
127
|
-
if (!result.success) {
|
|
128
|
-
this.state.initializationError = result.error?.message || 'Initialization failed';
|
|
129
|
-
return result;
|
|
130
|
-
}
|
|
131
|
-
this.state.isInitialized = true;
|
|
132
|
-
return successResult();
|
|
133
|
-
} finally {
|
|
134
|
-
this.initInProgress = false;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Wrap async operation with error handling and initialization check
|
|
140
|
-
*/
|
|
141
|
-
protected async execute<T>(
|
|
142
|
-
operation: () => Promise<T>,
|
|
143
|
-
errorCode?: string
|
|
144
|
-
): Promise<Result<T>> {
|
|
145
|
-
const initResult = await this.ensureInitialized();
|
|
146
|
-
if (!initResult.success) {
|
|
147
|
-
return {
|
|
148
|
-
success: false,
|
|
149
|
-
error: initResult.error,
|
|
150
|
-
};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
}
|
|
2
|
-
|
|
3
|
-
return this.errorHandler.handleAsync(operation, errorCode);
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Wrap sync operation with error handling
|
|
8
|
-
*/
|
|
9
|
-
protected executeSync<T>(operation: () => T, errorCode?: string): Result<T> {
|
|
10
|
-
return this.errorHandler.handle(operation, errorCode);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Check if service is initialized
|
|
15
|
-
*/
|
|
16
|
-
isInitialized(): boolean {
|
|
17
|
-
return this.state.isInitialized;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Get initialization error if any
|
|
22
|
-
*/
|
|
23
|
-
getInitializationError(): string | null {
|
|
24
|
-
return this.state.initializationError;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Reset service state
|
|
29
|
-
* Override to add custom cleanup logic
|
|
30
|
-
*/
|
|
31
|
-
reset(): void {
|
|
32
|
-
this.state = {
|
|
33
|
-
isInitialized: false,
|
|
34
|
-
initializationError: null,
|
|
35
|
-
};
|
|
36
|
-
this.initInProgress = false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get service name
|
|
41
|
-
*/
|
|
42
|
-
getServiceName(): string {
|
|
43
|
-
return this.serviceName;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Log in development mode
|
|
48
|
-
*/
|
|
49
|
-
protected log(message: string, ...args: unknown[]): void {
|
|
50
|
-
if (__DEV__) {
|
|
51
|
-
console.log(`[${this.serviceName}] ${message}`, ...args);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Log error in development mode
|
|
57
|
-
*/
|
|
58
|
-
protected logError(message: string, error?: unknown): void {
|
|
59
|
-
if (__DEV__) {
|
|
60
|
-
console.error(`[${this.serviceName}] ${message}`, error);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Create a failure result
|
|
66
|
-
*/
|
|
67
|
-
protected failure(code: string, message?: string): Result {
|
|
68
|
-
return this.errorHandler.failureFrom(code, message);
|
|
69
|
-
}
|
|
70
|
-
}
|