@oxyhq/services 5.9.2 → 5.9.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.
Files changed (202) hide show
  1. package/README.md +1 -33
  2. package/lib/commonjs/core/OxyServices.js +322 -0
  3. package/lib/commonjs/core/OxyServices.js.map +1 -0
  4. package/lib/commonjs/core/OxyServicesMain.js +51 -0
  5. package/lib/commonjs/core/OxyServicesMain.js.map +1 -0
  6. package/lib/commonjs/core/analytics/AnalyticsService.js +67 -0
  7. package/lib/commonjs/core/analytics/AnalyticsService.js.map +1 -0
  8. package/lib/commonjs/core/auth/AuthService.js +526 -0
  9. package/lib/commonjs/core/auth/AuthService.js.map +1 -0
  10. package/lib/commonjs/core/devices/DeviceService.js +61 -0
  11. package/lib/commonjs/core/devices/DeviceService.js.map +1 -0
  12. package/lib/commonjs/core/files/FileService.js +176 -0
  13. package/lib/commonjs/core/files/FileService.js.map +1 -0
  14. package/lib/commonjs/core/index.js +103 -1701
  15. package/lib/commonjs/core/index.js.map +1 -1
  16. package/lib/commonjs/core/karma/KarmaService.js +100 -0
  17. package/lib/commonjs/core/karma/KarmaService.js.map +1 -0
  18. package/lib/commonjs/core/locations/LocationService.js +131 -0
  19. package/lib/commonjs/core/locations/LocationService.js.map +1 -0
  20. package/lib/commonjs/core/payments/PaymentService.js +124 -0
  21. package/lib/commonjs/core/payments/PaymentService.js.map +1 -0
  22. package/lib/commonjs/core/users/UserService.js +234 -0
  23. package/lib/commonjs/core/users/UserService.js.map +1 -0
  24. package/lib/commonjs/index.js +164 -3
  25. package/lib/commonjs/index.js.map +1 -1
  26. package/lib/commonjs/models/session.js +2 -0
  27. package/lib/commonjs/{types/middleware.js.map → models/session.js.map} +1 -1
  28. package/lib/commonjs/ui/context/OxyContext.js +28 -24
  29. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  30. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +2 -2
  31. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/FileManagementScreen.js +12 -12
  33. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
  35. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/SignInScreen.js +1 -1
  38. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -1
  40. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  42. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
  44. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  45. package/lib/commonjs/ui/stores/followStore.js +4 -4
  46. package/lib/commonjs/ui/stores/followStore.js.map +1 -1
  47. package/lib/commonjs/utils/apiUtils.js +93 -0
  48. package/lib/commonjs/utils/apiUtils.js.map +1 -0
  49. package/lib/commonjs/utils/asyncUtils.js +219 -0
  50. package/lib/commonjs/utils/asyncUtils.js.map +1 -0
  51. package/lib/commonjs/utils/errorUtils.js +148 -0
  52. package/lib/commonjs/utils/errorUtils.js.map +1 -0
  53. package/lib/commonjs/utils/hookUtils.js +399 -0
  54. package/lib/commonjs/utils/hookUtils.js.map +1 -0
  55. package/lib/commonjs/utils/loggerUtils.js +160 -0
  56. package/lib/commonjs/utils/loggerUtils.js.map +1 -0
  57. package/lib/commonjs/utils/validationUtils.js +174 -0
  58. package/lib/commonjs/utils/validationUtils.js.map +1 -0
  59. package/lib/module/core/OxyServices.js +316 -0
  60. package/lib/module/core/OxyServices.js.map +1 -0
  61. package/lib/module/core/OxyServicesMain.js +47 -0
  62. package/lib/module/core/OxyServicesMain.js.map +1 -0
  63. package/lib/module/core/analytics/AnalyticsService.js +62 -0
  64. package/lib/module/core/analytics/AnalyticsService.js.map +1 -0
  65. package/lib/module/core/auth/AuthService.js +521 -0
  66. package/lib/module/core/auth/AuthService.js.map +1 -0
  67. package/lib/module/core/devices/DeviceService.js +57 -0
  68. package/lib/module/core/devices/DeviceService.js.map +1 -0
  69. package/lib/module/core/files/FileService.js +171 -0
  70. package/lib/module/core/files/FileService.js.map +1 -0
  71. package/lib/module/core/index.js +25 -1690
  72. package/lib/module/core/index.js.map +1 -1
  73. package/lib/module/core/karma/KarmaService.js +95 -0
  74. package/lib/module/core/karma/KarmaService.js.map +1 -0
  75. package/lib/module/core/locations/LocationService.js +127 -0
  76. package/lib/module/core/locations/LocationService.js.map +1 -0
  77. package/lib/module/core/payments/PaymentService.js +119 -0
  78. package/lib/module/core/payments/PaymentService.js.map +1 -0
  79. package/lib/module/core/users/UserService.js +230 -0
  80. package/lib/module/core/users/UserService.js.map +1 -0
  81. package/lib/module/index.js +8 -4
  82. package/lib/module/index.js.map +1 -1
  83. package/lib/module/models/session.js +2 -0
  84. package/lib/module/{types/middleware.js.map → models/session.js.map} +1 -1
  85. package/lib/module/ui/context/OxyContext.js +28 -24
  86. package/lib/module/ui/context/OxyContext.js.map +1 -1
  87. package/lib/module/ui/screens/AccountSwitcherScreen.js +2 -2
  88. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  89. package/lib/module/ui/screens/FileManagementScreen.js +12 -12
  90. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  91. package/lib/module/ui/screens/ProfileScreen.js +2 -2
  92. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  93. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  94. package/lib/module/ui/screens/SignInScreen.js +1 -1
  95. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  96. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
  97. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  98. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  99. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  100. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  101. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  102. package/lib/module/ui/stores/followStore.js +4 -4
  103. package/lib/module/ui/stores/followStore.js.map +1 -1
  104. package/lib/module/utils/apiUtils.js +85 -0
  105. package/lib/module/utils/apiUtils.js.map +1 -0
  106. package/lib/module/utils/asyncUtils.js +202 -0
  107. package/lib/module/utils/asyncUtils.js.map +1 -0
  108. package/lib/module/utils/errorUtils.js +139 -0
  109. package/lib/module/utils/errorUtils.js.map +1 -0
  110. package/lib/module/utils/hookUtils.js +381 -0
  111. package/lib/module/utils/hookUtils.js.map +1 -0
  112. package/lib/module/utils/loggerUtils.js +149 -0
  113. package/lib/module/utils/loggerUtils.js.map +1 -0
  114. package/lib/module/utils/validationUtils.js +154 -0
  115. package/lib/module/utils/validationUtils.js.map +1 -0
  116. package/lib/typescript/core/OxyServices.d.ts +99 -0
  117. package/lib/typescript/core/OxyServices.d.ts.map +1 -0
  118. package/lib/typescript/core/OxyServicesMain.d.ts +33 -0
  119. package/lib/typescript/core/OxyServicesMain.d.ts.map +1 -0
  120. package/lib/typescript/core/analytics/AnalyticsService.d.ts +26 -0
  121. package/lib/typescript/core/analytics/AnalyticsService.d.ts.map +1 -0
  122. package/lib/typescript/core/auth/AuthService.d.ts +165 -0
  123. package/lib/typescript/core/auth/AuthService.d.ts.map +1 -0
  124. package/lib/typescript/core/devices/DeviceService.d.ts +20 -0
  125. package/lib/typescript/core/devices/DeviceService.d.ts.map +1 -0
  126. package/lib/typescript/core/files/FileService.d.ts +59 -0
  127. package/lib/typescript/core/files/FileService.d.ts.map +1 -0
  128. package/lib/typescript/core/index.d.ts +19 -656
  129. package/lib/typescript/core/index.d.ts.map +1 -1
  130. package/lib/typescript/core/karma/KarmaService.d.ts +50 -0
  131. package/lib/typescript/core/karma/KarmaService.d.ts.map +1 -0
  132. package/lib/typescript/core/locations/LocationService.d.ts +39 -0
  133. package/lib/typescript/core/locations/LocationService.d.ts.map +1 -0
  134. package/lib/typescript/core/payments/PaymentService.d.ts +50 -0
  135. package/lib/typescript/core/payments/PaymentService.d.ts.map +1 -0
  136. package/lib/typescript/core/users/UserService.d.ts +111 -0
  137. package/lib/typescript/core/users/UserService.d.ts.map +1 -0
  138. package/lib/typescript/index.d.ts +7 -3
  139. package/lib/typescript/index.d.ts.map +1 -1
  140. package/lib/typescript/models/{secureSession.d.ts → session.d.ts} +4 -4
  141. package/lib/typescript/models/session.d.ts.map +1 -0
  142. package/lib/typescript/ui/context/OxyContext.d.ts +2 -2
  143. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  144. package/lib/typescript/utils/apiUtils.d.ts +61 -0
  145. package/lib/typescript/utils/apiUtils.d.ts.map +1 -0
  146. package/lib/typescript/utils/asyncUtils.d.ts +64 -0
  147. package/lib/typescript/utils/asyncUtils.d.ts.map +1 -0
  148. package/lib/typescript/utils/errorUtils.d.ts +45 -0
  149. package/lib/typescript/utils/errorUtils.d.ts.map +1 -0
  150. package/lib/typescript/utils/hookUtils.d.ts +102 -0
  151. package/lib/typescript/utils/hookUtils.d.ts.map +1 -0
  152. package/lib/typescript/utils/loggerUtils.d.ts +49 -0
  153. package/lib/typescript/utils/loggerUtils.d.ts.map +1 -0
  154. package/lib/typescript/utils/validationUtils.d.ts +80 -0
  155. package/lib/typescript/utils/validationUtils.d.ts.map +1 -0
  156. package/package.json +2 -8
  157. package/src/core/OxyServices.ts +351 -0
  158. package/src/core/OxyServicesMain.ts +57 -0
  159. package/src/core/analytics/AnalyticsService.ts +64 -0
  160. package/src/core/auth/AuthService.ts +544 -0
  161. package/src/core/devices/DeviceService.ts +55 -0
  162. package/src/core/files/FileService.ts +194 -0
  163. package/src/core/index.ts +27 -1765
  164. package/src/core/karma/KarmaService.ts +104 -0
  165. package/src/core/locations/LocationService.ts +141 -0
  166. package/src/core/payments/PaymentService.ts +133 -0
  167. package/src/core/users/UserService.ts +241 -0
  168. package/src/index.ts +29 -8
  169. package/src/models/{secureSession.ts → session.ts} +5 -5
  170. package/src/ui/context/OxyContext.tsx +34 -30
  171. package/src/ui/screens/AccountSwitcherScreen.tsx +4 -4
  172. package/src/ui/screens/FileManagementScreen.tsx +12 -12
  173. package/src/ui/screens/ProfileScreen.tsx +3 -3
  174. package/src/ui/screens/SessionManagementScreen.tsx +2 -2
  175. package/src/ui/screens/SignInScreen.tsx +1 -1
  176. package/src/ui/screens/karma/KarmaCenterScreen.tsx +2 -2
  177. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +3 -3
  178. package/src/ui/screens/karma/KarmaRulesScreen.tsx +3 -3
  179. package/src/ui/stores/followStore.ts +4 -4
  180. package/src/utils/apiUtils.ts +102 -0
  181. package/src/utils/asyncUtils.ts +265 -0
  182. package/src/utils/errorUtils.ts +172 -0
  183. package/src/utils/hookUtils.ts +397 -0
  184. package/src/utils/loggerUtils.ts +153 -0
  185. package/src/utils/validationUtils.ts +158 -0
  186. package/lib/commonjs/middleware.js +0 -17
  187. package/lib/commonjs/middleware.js.map +0 -1
  188. package/lib/commonjs/models/secureSession.js +0 -2
  189. package/lib/commonjs/models/secureSession.js.map +0 -1
  190. package/lib/commonjs/types/middleware.js +0 -6
  191. package/lib/module/middleware.js +0 -12
  192. package/lib/module/middleware.js.map +0 -1
  193. package/lib/module/models/secureSession.js +0 -2
  194. package/lib/module/models/secureSession.js.map +0 -1
  195. package/lib/module/types/middleware.js +0 -4
  196. package/lib/typescript/middleware.d.ts +0 -9
  197. package/lib/typescript/middleware.d.ts.map +0 -1
  198. package/lib/typescript/models/secureSession.d.ts.map +0 -1
  199. package/lib/typescript/types/middleware.d.ts +0 -19
  200. package/lib/typescript/types/middleware.d.ts.map +0 -1
  201. package/src/middleware.ts +0 -11
  202. package/src/types/middleware.ts +0 -20
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Async utilities for common asynchronous patterns and error handling
3
+ */
4
+
5
+ /**
6
+ * Wrapper for async operations with automatic error handling
7
+ */
8
+ export async function withErrorHandling<T>(
9
+ operation: () => Promise<T>,
10
+ errorHandler?: (error: any) => void,
11
+ context?: string
12
+ ): Promise<T | null> {
13
+ try {
14
+ return await operation();
15
+ } catch (error) {
16
+ if (errorHandler) {
17
+ errorHandler(error);
18
+ } else {
19
+ console.error(`Error in ${context || 'operation'}:`, error);
20
+ }
21
+ return null;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Execute multiple async operations in parallel with error handling
27
+ */
28
+ export async function parallelWithErrorHandling<T>(
29
+ operations: (() => Promise<T>)[],
30
+ errorHandler?: (error: any, index: number) => void
31
+ ): Promise<(T | null)[]> {
32
+ const results = await Promise.allSettled(
33
+ operations.map((op, index) =>
34
+ withErrorHandling(op, error => errorHandler?.(error, index))
35
+ )
36
+ );
37
+
38
+ return results.map(result =>
39
+ result.status === 'fulfilled' ? result.value : null
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Retry an async operation with exponential backoff
45
+ */
46
+ export async function retryAsync<T>(
47
+ operation: () => Promise<T>,
48
+ maxRetries: number = 3,
49
+ baseDelay: number = 1000,
50
+ shouldRetry?: (error: any) => boolean
51
+ ): Promise<T> {
52
+ let lastError: any;
53
+
54
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
55
+ try {
56
+ return await operation();
57
+ } catch (error) {
58
+ lastError = error;
59
+
60
+ if (attempt === maxRetries) {
61
+ break;
62
+ }
63
+
64
+ if (shouldRetry && !shouldRetry(error)) {
65
+ break;
66
+ }
67
+
68
+ const delay = baseDelay * Math.pow(2, attempt);
69
+ await new Promise(resolve => setTimeout(resolve, delay));
70
+ }
71
+ }
72
+
73
+ throw lastError;
74
+ }
75
+
76
+ /**
77
+ * Debounce async function calls
78
+ */
79
+ export function debounceAsync<T extends (...args: any[]) => Promise<any>>(
80
+ func: T,
81
+ delay: number
82
+ ): (...args: Parameters<T>) => Promise<ReturnType<T>> {
83
+ let timeoutId: NodeJS.Timeout;
84
+ let lastPromise: Promise<ReturnType<T>> | null = null;
85
+
86
+ return (...args: Parameters<T>): Promise<ReturnType<T>> => {
87
+ return new Promise((resolve, reject) => {
88
+ clearTimeout(timeoutId);
89
+
90
+ timeoutId = setTimeout(async () => {
91
+ try {
92
+ const result = await func(...args);
93
+ resolve(result);
94
+ } catch (error) {
95
+ reject(error);
96
+ }
97
+ }, delay);
98
+ });
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Throttle async function calls
104
+ */
105
+ export function throttleAsync<T extends (...args: any[]) => Promise<any>>(
106
+ func: T,
107
+ limit: number,
108
+ interval: number
109
+ ): (...args: Parameters<T>) => Promise<ReturnType<T>> {
110
+ let inThrottle = false;
111
+ let lastPromise: Promise<ReturnType<T>> | null = null;
112
+
113
+ return (...args: Parameters<T>): Promise<ReturnType<T>> => {
114
+ if (inThrottle) {
115
+ return lastPromise!;
116
+ }
117
+
118
+ inThrottle = true;
119
+ lastPromise = func(...args);
120
+
121
+ setTimeout(() => {
122
+ inThrottle = false;
123
+ }, interval);
124
+
125
+ return lastPromise;
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Execute async operations sequentially with progress tracking
131
+ */
132
+ export async function sequentialWithProgress<T>(
133
+ operations: (() => Promise<T>)[],
134
+ onProgress?: (completed: number, total: number) => void
135
+ ): Promise<T[]> {
136
+ const results: T[] = [];
137
+
138
+ for (let i = 0; i < operations.length; i++) {
139
+ const result = await operations[i]();
140
+ results.push(result);
141
+ onProgress?.(i + 1, operations.length);
142
+ }
143
+
144
+ return results;
145
+ }
146
+
147
+ /**
148
+ * Batch async operations
149
+ */
150
+ export async function batchAsync<T>(
151
+ items: T[],
152
+ batchSize: number,
153
+ processor: (batch: T[]) => Promise<void>
154
+ ): Promise<void> {
155
+ for (let i = 0; i < items.length; i += batchSize) {
156
+ const batch = items.slice(i, i + batchSize);
157
+ await processor(batch);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Create a cancellable async operation
163
+ */
164
+ export function createCancellableAsync<T>(
165
+ operation: (signal: AbortSignal) => Promise<T>
166
+ ): { execute: () => Promise<T>; cancel: () => void } {
167
+ let abortController: AbortController | null = null;
168
+
169
+ return {
170
+ execute: async () => {
171
+ abortController = new AbortController();
172
+ return await operation(abortController.signal);
173
+ },
174
+ cancel: () => {
175
+ abortController?.abort();
176
+ }
177
+ };
178
+ }
179
+
180
+ /**
181
+ * Timeout wrapper for async operations
182
+ */
183
+ export async function withTimeout<T>(
184
+ operation: Promise<T>,
185
+ timeoutMs: number,
186
+ timeoutMessage?: string
187
+ ): Promise<T> {
188
+ const timeoutPromise = new Promise<never>((_, reject) => {
189
+ setTimeout(() => {
190
+ reject(new Error(timeoutMessage || `Operation timed out after ${timeoutMs}ms`));
191
+ }, timeoutMs);
192
+ });
193
+
194
+ return Promise.race([operation, timeoutPromise]);
195
+ }
196
+
197
+ /**
198
+ * Cache async operation results
199
+ */
200
+ export function createAsyncCache<T>(
201
+ ttl: number = 5 * 60 * 1000 // 5 minutes default
202
+ ) {
203
+ const cache = new Map<string, { data: T; timestamp: number }>();
204
+
205
+ return {
206
+ get: (key: string): T | null => {
207
+ const item = cache.get(key);
208
+ if (!item) return null;
209
+
210
+ if (Date.now() - item.timestamp > ttl) {
211
+ cache.delete(key);
212
+ return null;
213
+ }
214
+
215
+ return item.data;
216
+ },
217
+
218
+ set: (key: string, data: T): void => {
219
+ cache.set(key, { data, timestamp: Date.now() });
220
+ },
221
+
222
+ clear: (): void => {
223
+ cache.clear();
224
+ },
225
+
226
+ delete: (key: string): boolean => {
227
+ return cache.delete(key);
228
+ }
229
+ };
230
+ }
231
+
232
+ /**
233
+ * Execute async operation with loading state
234
+ */
235
+ export async function withLoadingState<T>(
236
+ operation: () => Promise<T>,
237
+ setLoading: (loading: boolean) => void
238
+ ): Promise<T> {
239
+ setLoading(true);
240
+ try {
241
+ return await operation();
242
+ } finally {
243
+ setLoading(false);
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Create a promise that resolves after a delay
249
+ */
250
+ export const delay = (ms: number): Promise<void> =>
251
+ new Promise(resolve => setTimeout(resolve, ms));
252
+
253
+ /**
254
+ * Execute async operation with retry on specific errors
255
+ */
256
+ export async function retryOnError<T>(
257
+ operation: () => Promise<T>,
258
+ retryableErrors: (string | number)[],
259
+ maxRetries: number = 3
260
+ ): Promise<T> {
261
+ return retryAsync(operation, maxRetries, 1000, (error) => {
262
+ const errorCode = error?.code || error?.status || error?.message;
263
+ return retryableErrors.includes(errorCode);
264
+ });
265
+ }
@@ -0,0 +1,172 @@
1
+ import { ApiError } from '../models/interfaces';
2
+
3
+ /**
4
+ * Error handling utilities for consistent error processing
5
+ */
6
+
7
+ /**
8
+ * Common error codes
9
+ */
10
+ export const ErrorCodes = {
11
+ // Authentication errors
12
+ UNAUTHORIZED: 'UNAUTHORIZED',
13
+ FORBIDDEN: 'FORBIDDEN',
14
+ INVALID_TOKEN: 'INVALID_TOKEN',
15
+ MISSING_TOKEN: 'MISSING_TOKEN',
16
+
17
+ // Validation errors
18
+ VALIDATION_ERROR: 'VALIDATION_ERROR',
19
+ MISSING_PARAMETER: 'MISSING_PARAMETER',
20
+ INVALID_FORMAT: 'INVALID_FORMAT',
21
+
22
+ // Resource errors
23
+ NOT_FOUND: 'NOT_FOUND',
24
+ ALREADY_EXISTS: 'ALREADY_EXISTS',
25
+ CONFLICT: 'CONFLICT',
26
+
27
+ // Server errors
28
+ INTERNAL_ERROR: 'INTERNAL_ERROR',
29
+ SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
30
+ TIMEOUT: 'TIMEOUT',
31
+
32
+ // Network errors
33
+ NETWORK_ERROR: 'NETWORK_ERROR',
34
+ CONNECTION_FAILED: 'CONNECTION_FAILED'
35
+ } as const;
36
+
37
+ /**
38
+ * Create a standardized API error
39
+ */
40
+ export function createApiError(
41
+ message: string,
42
+ code: string = ErrorCodes.INTERNAL_ERROR,
43
+ status: number = 500,
44
+ details?: any
45
+ ): ApiError {
46
+ return {
47
+ message,
48
+ code,
49
+ status,
50
+ details
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Handle common HTTP errors and convert to ApiError
56
+ */
57
+ export function handleHttpError(error: any): ApiError {
58
+ // If it's already an ApiError, return it
59
+ if (error && typeof error === 'object' && 'code' in error && 'status' in error) {
60
+ return error as ApiError;
61
+ }
62
+
63
+ // Handle axios errors
64
+ if (error?.response) {
65
+ const { status, data } = error.response;
66
+
67
+ return createApiError(
68
+ data?.message || `HTTP ${status} error`,
69
+ data?.code || getErrorCodeFromStatus(status),
70
+ status,
71
+ data
72
+ );
73
+ }
74
+
75
+ // Handle network errors
76
+ if (error?.request) {
77
+ return createApiError(
78
+ 'Network error - no response received',
79
+ ErrorCodes.NETWORK_ERROR,
80
+ 0
81
+ );
82
+ }
83
+
84
+ // Handle other errors
85
+ return createApiError(
86
+ error?.message || 'Unknown error occurred',
87
+ ErrorCodes.INTERNAL_ERROR,
88
+ 500
89
+ );
90
+ }
91
+
92
+ /**
93
+ * Get error code from HTTP status
94
+ */
95
+ function getErrorCodeFromStatus(status: number): string {
96
+ switch (status) {
97
+ case 400:
98
+ return ErrorCodes.VALIDATION_ERROR;
99
+ case 401:
100
+ return ErrorCodes.UNAUTHORIZED;
101
+ case 403:
102
+ return ErrorCodes.FORBIDDEN;
103
+ case 404:
104
+ return ErrorCodes.NOT_FOUND;
105
+ case 409:
106
+ return ErrorCodes.CONFLICT;
107
+ case 422:
108
+ return ErrorCodes.VALIDATION_ERROR;
109
+ case 500:
110
+ return ErrorCodes.INTERNAL_ERROR;
111
+ case 503:
112
+ return ErrorCodes.SERVICE_UNAVAILABLE;
113
+ default:
114
+ return ErrorCodes.INTERNAL_ERROR;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Validate required fields and throw error if missing
120
+ */
121
+ export function validateRequiredFields(data: Record<string, any>, fields: string[]): void {
122
+ const missing = fields.filter(field => !data[field]);
123
+
124
+ if (missing.length > 0) {
125
+ throw createApiError(
126
+ `Missing required fields: ${missing.join(', ')}`,
127
+ ErrorCodes.MISSING_PARAMETER,
128
+ 400
129
+ );
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Safe error logging with context
135
+ */
136
+ export function logError(error: any, context?: string): void {
137
+ const prefix = context ? `[${context}]` : '[Error]';
138
+
139
+ if (error instanceof Error) {
140
+ console.error(`${prefix} ${error.message}`, error.stack);
141
+ } else {
142
+ console.error(`${prefix}`, error);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Retry function with exponential backoff
148
+ */
149
+ export async function retryWithBackoff<T>(
150
+ fn: () => Promise<T>,
151
+ maxRetries: number = 3,
152
+ baseDelay: number = 1000
153
+ ): Promise<T> {
154
+ let lastError: any;
155
+
156
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
157
+ try {
158
+ return await fn();
159
+ } catch (error) {
160
+ lastError = error;
161
+
162
+ if (attempt === maxRetries) {
163
+ break;
164
+ }
165
+
166
+ const delay = baseDelay * Math.pow(2, attempt);
167
+ await new Promise(resolve => setTimeout(resolve, delay));
168
+ }
169
+ }
170
+
171
+ throw lastError;
172
+ }