create-fluxstack 1.16.0 → 1.17.0

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 (119) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/app/client/src/App.tsx +8 -0
  3. package/app/client/src/live/AuthDemo.tsx +4 -4
  4. package/core/build/bundler.ts +40 -26
  5. package/core/build/flux-plugins-generator.ts +325 -325
  6. package/core/build/index.ts +92 -21
  7. package/core/cli/command-registry.ts +44 -46
  8. package/core/cli/commands/build.ts +11 -6
  9. package/core/cli/commands/create.ts +7 -5
  10. package/core/cli/commands/dev.ts +6 -5
  11. package/core/cli/commands/help.ts +3 -2
  12. package/core/cli/commands/make-plugin.ts +8 -7
  13. package/core/cli/commands/plugin-add.ts +60 -43
  14. package/core/cli/commands/plugin-deps.ts +73 -57
  15. package/core/cli/commands/plugin-list.ts +44 -41
  16. package/core/cli/commands/plugin-remove.ts +33 -22
  17. package/core/cli/generators/component.ts +770 -769
  18. package/core/cli/generators/controller.ts +9 -8
  19. package/core/cli/generators/index.ts +148 -146
  20. package/core/cli/generators/interactive.ts +228 -227
  21. package/core/cli/generators/plugin.ts +11 -10
  22. package/core/cli/generators/prompts.ts +83 -82
  23. package/core/cli/generators/route.ts +7 -6
  24. package/core/cli/generators/service.ts +10 -9
  25. package/core/cli/generators/template-engine.ts +2 -1
  26. package/core/cli/generators/types.ts +7 -7
  27. package/core/cli/generators/utils.ts +191 -191
  28. package/core/cli/index.ts +9 -8
  29. package/core/cli/plugin-discovery.ts +2 -2
  30. package/core/client/hooks/useAuth.ts +48 -48
  31. package/core/client/standalone.ts +18 -17
  32. package/core/client/state/createStore.ts +192 -192
  33. package/core/client/state/index.ts +14 -14
  34. package/core/config/index.ts +1 -0
  35. package/core/framework/client.ts +131 -131
  36. package/core/framework/index.ts +7 -7
  37. package/core/framework/server.ts +72 -112
  38. package/core/framework/types.ts +2 -2
  39. package/core/plugins/built-in/live-components/commands/create-live-component.ts +6 -3
  40. package/core/plugins/built-in/monitoring/index.ts +110 -68
  41. package/core/plugins/built-in/static/index.ts +2 -2
  42. package/core/plugins/built-in/swagger/index.ts +9 -9
  43. package/core/plugins/built-in/vite/index.ts +3 -3
  44. package/core/plugins/built-in/vite/vite-dev.ts +3 -3
  45. package/core/plugins/config.ts +50 -47
  46. package/core/plugins/discovery.ts +10 -4
  47. package/core/plugins/executor.ts +2 -2
  48. package/core/plugins/index.ts +206 -203
  49. package/core/plugins/manager.ts +21 -20
  50. package/core/plugins/registry.ts +76 -12
  51. package/core/plugins/types.ts +14 -14
  52. package/core/server/framework.ts +3 -189
  53. package/core/server/live/auto-generated-components.ts +11 -29
  54. package/core/server/live/index.ts +41 -31
  55. package/core/server/live/websocket-plugin.ts +11 -1
  56. package/core/server/middleware/elysia-helpers.ts +16 -15
  57. package/core/server/middleware/errorHandling.ts +14 -14
  58. package/core/server/middleware/index.ts +31 -31
  59. package/core/server/plugins/database.ts +181 -180
  60. package/core/server/plugins/static-files-plugin.ts +4 -3
  61. package/core/server/plugins/swagger.ts +11 -8
  62. package/core/server/rooms/RoomBroadcaster.ts +11 -10
  63. package/core/server/rooms/RoomSystem.ts +14 -11
  64. package/core/server/services/BaseService.ts +7 -7
  65. package/core/server/services/ServiceContainer.ts +5 -5
  66. package/core/server/services/index.ts +8 -8
  67. package/core/templates/create-project.ts +28 -27
  68. package/core/testing/index.ts +9 -9
  69. package/core/testing/setup.ts +73 -73
  70. package/core/types/api.ts +168 -168
  71. package/core/types/config.ts +5 -5
  72. package/core/types/index.ts +1 -1
  73. package/core/types/plugin.ts +2 -2
  74. package/core/types/types.ts +3 -3
  75. package/core/utils/build-logger.ts +324 -324
  76. package/core/utils/config-schema.ts +480 -480
  77. package/core/utils/env.ts +10 -8
  78. package/core/utils/errors/codes.ts +114 -114
  79. package/core/utils/errors/handlers.ts +30 -20
  80. package/core/utils/errors/index.ts +54 -46
  81. package/core/utils/errors/middleware.ts +113 -113
  82. package/core/utils/helpers.ts +19 -16
  83. package/core/utils/logger/colors.ts +114 -114
  84. package/core/utils/logger/config.ts +2 -2
  85. package/core/utils/logger/formatter.ts +82 -82
  86. package/core/utils/logger/group-logger.ts +101 -101
  87. package/core/utils/logger/index.ts +13 -3
  88. package/core/utils/logger/startup-banner.ts +2 -2
  89. package/core/utils/logger/winston-logger.ts +152 -152
  90. package/core/utils/monitoring/index.ts +211 -211
  91. package/core/utils/sync-version.ts +67 -66
  92. package/core/utils/version.ts +1 -1
  93. package/package.json +104 -100
  94. package/playwright-report/index.html +85 -0
  95. package/playwright.config.ts +31 -0
  96. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  97. package/plugins/crypto-auth/client/components/index.ts +11 -11
  98. package/plugins/crypto-auth/client/index.ts +11 -11
  99. package/plugins/crypto-auth/package.json +65 -65
  100. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  101. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +6 -5
  102. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +6 -5
  103. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +3 -3
  104. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  105. package/plugins/crypto-auth/server/middlewares.ts +19 -19
  106. package/vite.config.ts +13 -0
  107. package/app/client/.live-stubs/LiveAdminPanel.js +0 -5
  108. package/app/client/.live-stubs/LiveCounter.js +0 -9
  109. package/app/client/.live-stubs/LiveForm.js +0 -11
  110. package/app/client/.live-stubs/LiveLocalCounter.js +0 -8
  111. package/app/client/.live-stubs/LivePingPong.js +0 -10
  112. package/app/client/.live-stubs/LiveRoomChat.js +0 -11
  113. package/app/client/.live-stubs/LiveSharedCounter.js +0 -10
  114. package/app/client/.live-stubs/LiveUpload.js +0 -15
  115. package/app/server/live/register-components.ts +0 -19
  116. package/core/build/live-components-generator.ts +0 -321
  117. package/core/live/ComponentRegistry.ts +0 -403
  118. package/core/live/types.ts +0 -241
  119. package/workspace.json +0 -6
package/core/utils/env.ts CHANGED
@@ -27,7 +27,7 @@
27
27
  * Uses Bun.env (runtime) → process.env (fallback) → eval (last resort)
28
28
  */
29
29
  class EnvLoader {
30
- private cache = new Map<string, any>()
30
+ private cache = new Map<string, unknown>()
31
31
  private accessor: () => Record<string, string | undefined>
32
32
 
33
33
  constructor() {
@@ -38,17 +38,19 @@ class EnvLoader {
38
38
  * Create dynamic accessor to prevent build-time inlining
39
39
  */
40
40
  private createAccessor(): () => Record<string, string | undefined> {
41
- const global = globalThis as any
41
+ const global = globalThis as unknown as Record<string, Record<string, unknown> | undefined>
42
42
 
43
43
  return () => {
44
44
  // Try Bun.env first (most reliable in Bun)
45
- if (global['Bun']?.['env']) {
46
- return global['Bun']['env']
45
+ const bun = global['Bun'] as Record<string, unknown> | undefined
46
+ if (bun?.['env']) {
47
+ return bun['env'] as Record<string, string | undefined>
47
48
  }
48
49
 
49
50
  // Fallback to process.env
50
- if (global['process']?.['env']) {
51
- return global['process']['env']
51
+ const proc = global['process'] as Record<string, unknown> | undefined
52
+ if (proc?.['env']) {
53
+ return proc['env'] as Record<string, string | undefined>
52
54
  }
53
55
 
54
56
  return {}
@@ -63,7 +65,7 @@ class EnvLoader {
63
65
  // Check cache first
64
66
  const cacheKey = `${key}:${typeof defaultValue}`
65
67
  if (this.cache.has(cacheKey)) {
66
- return this.cache.get(cacheKey)
68
+ return this.cache.get(cacheKey) as T
67
69
  }
68
70
 
69
71
  const env = this.accessor()
@@ -75,7 +77,7 @@ class EnvLoader {
75
77
  }
76
78
 
77
79
  // Auto-detect type from defaultValue
78
- let result: any = value
80
+ let result: unknown = value
79
81
 
80
82
  if (typeof defaultValue === 'number') {
81
83
  const parsed = Number(value)
@@ -1,115 +1,115 @@
1
- export const ERROR_CODES = {
2
- // Validation errors (400)
3
- VALIDATION_ERROR: 'VALIDATION_ERROR',
4
- INVALID_INPUT: 'INVALID_INPUT',
5
- MISSING_REQUIRED_FIELD: 'MISSING_REQUIRED_FIELD',
6
- INVALID_FORMAT: 'INVALID_FORMAT',
7
-
8
- // Authentication errors (401)
9
- UNAUTHORIZED: 'UNAUTHORIZED',
10
- INVALID_TOKEN: 'INVALID_TOKEN',
11
- TOKEN_EXPIRED: 'TOKEN_EXPIRED',
12
- INVALID_CREDENTIALS: 'INVALID_CREDENTIALS',
13
-
14
- // Authorization errors (403)
15
- FORBIDDEN: 'FORBIDDEN',
16
- INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',
17
- ACCESS_DENIED: 'ACCESS_DENIED',
18
-
19
- // Not found errors (404)
20
- NOT_FOUND: 'NOT_FOUND',
21
- RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
22
- ENDPOINT_NOT_FOUND: 'ENDPOINT_NOT_FOUND',
23
-
24
- // Conflict errors (409)
25
- CONFLICT: 'CONFLICT',
26
- RESOURCE_ALREADY_EXISTS: 'RESOURCE_ALREADY_EXISTS',
27
- DUPLICATE_ENTRY: 'DUPLICATE_ENTRY',
28
-
29
- // Server errors (500)
30
- INTERNAL_ERROR: 'INTERNAL_ERROR',
31
- INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
32
- DATABASE_ERROR: 'DATABASE_ERROR',
33
- EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',
34
-
35
- // Service unavailable (503)
36
- SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
37
- MAINTENANCE_MODE: 'MAINTENANCE_MODE',
38
- RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
39
-
40
- // Plugin errors
41
- PLUGIN_ERROR: 'PLUGIN_ERROR',
42
- PLUGIN_NOT_FOUND: 'PLUGIN_NOT_FOUND',
43
- PLUGIN_INITIALIZATION_ERROR: 'PLUGIN_INITIALIZATION_ERROR',
44
-
45
- // Configuration errors
46
- CONFIG_ERROR: 'CONFIG_ERROR',
47
- INVALID_CONFIG: 'INVALID_CONFIG',
48
- MISSING_CONFIG: 'MISSING_CONFIG',
49
-
50
- // Build errors
51
- BUILD_ERROR: 'BUILD_ERROR',
52
- COMPILATION_ERROR: 'COMPILATION_ERROR',
53
- BUNDLING_ERROR: 'BUNDLING_ERROR'
54
- } as const
55
-
56
- export type ErrorCode = typeof ERROR_CODES[keyof typeof ERROR_CODES]
57
-
58
- export const getErrorMessage = (code: ErrorCode): string => {
59
- const messages: Record<ErrorCode, string> = {
60
- // Validation errors
61
- VALIDATION_ERROR: 'Validation failed',
62
- INVALID_INPUT: 'Invalid input provided',
63
- MISSING_REQUIRED_FIELD: 'Required field is missing',
64
- INVALID_FORMAT: 'Invalid format',
65
-
66
- // Authentication errors
67
- UNAUTHORIZED: 'Authentication required',
68
- INVALID_TOKEN: 'Invalid authentication token',
69
- TOKEN_EXPIRED: 'Authentication token has expired',
70
- INVALID_CREDENTIALS: 'Invalid credentials provided',
71
-
72
- // Authorization errors
73
- FORBIDDEN: 'Access forbidden',
74
- INSUFFICIENT_PERMISSIONS: 'Insufficient permissions',
75
- ACCESS_DENIED: 'Access denied',
76
-
77
- // Not found errors
78
- NOT_FOUND: 'Resource not found',
79
- RESOURCE_NOT_FOUND: 'Requested resource not found',
80
- ENDPOINT_NOT_FOUND: 'API endpoint not found',
81
-
82
- // Conflict errors
83
- CONFLICT: 'Resource conflict',
84
- RESOURCE_ALREADY_EXISTS: 'Resource already exists',
85
- DUPLICATE_ENTRY: 'Duplicate entry',
86
-
87
- // Server errors
88
- INTERNAL_ERROR: 'Internal server error',
89
- INTERNAL_SERVER_ERROR: 'Internal server error',
90
- DATABASE_ERROR: 'Database operation failed',
91
- EXTERNAL_SERVICE_ERROR: 'External service error',
92
-
93
- // Service unavailable
94
- SERVICE_UNAVAILABLE: 'Service temporarily unavailable',
95
- MAINTENANCE_MODE: 'Service is under maintenance',
96
- RATE_LIMIT_EXCEEDED: 'Rate limit exceeded',
97
-
98
- // Plugin errors
99
- PLUGIN_ERROR: 'Plugin error',
100
- PLUGIN_NOT_FOUND: 'Plugin not found',
101
- PLUGIN_INITIALIZATION_ERROR: 'Plugin initialization failed',
102
-
103
- // Configuration errors
104
- CONFIG_ERROR: 'Configuration error',
105
- INVALID_CONFIG: 'Invalid configuration',
106
- MISSING_CONFIG: 'Missing configuration',
107
-
108
- // Build errors
109
- BUILD_ERROR: 'Build error',
110
- COMPILATION_ERROR: 'Compilation failed',
111
- BUNDLING_ERROR: 'Bundling failed'
112
- }
113
-
114
- return messages[code] || 'Unknown error'
1
+ export const ERROR_CODES = {
2
+ // Validation errors (400)
3
+ VALIDATION_ERROR: 'VALIDATION_ERROR',
4
+ INVALID_INPUT: 'INVALID_INPUT',
5
+ MISSING_REQUIRED_FIELD: 'MISSING_REQUIRED_FIELD',
6
+ INVALID_FORMAT: 'INVALID_FORMAT',
7
+
8
+ // Authentication errors (401)
9
+ UNAUTHORIZED: 'UNAUTHORIZED',
10
+ INVALID_TOKEN: 'INVALID_TOKEN',
11
+ TOKEN_EXPIRED: 'TOKEN_EXPIRED',
12
+ INVALID_CREDENTIALS: 'INVALID_CREDENTIALS',
13
+
14
+ // Authorization errors (403)
15
+ FORBIDDEN: 'FORBIDDEN',
16
+ INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',
17
+ ACCESS_DENIED: 'ACCESS_DENIED',
18
+
19
+ // Not found errors (404)
20
+ NOT_FOUND: 'NOT_FOUND',
21
+ RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
22
+ ENDPOINT_NOT_FOUND: 'ENDPOINT_NOT_FOUND',
23
+
24
+ // Conflict errors (409)
25
+ CONFLICT: 'CONFLICT',
26
+ RESOURCE_ALREADY_EXISTS: 'RESOURCE_ALREADY_EXISTS',
27
+ DUPLICATE_ENTRY: 'DUPLICATE_ENTRY',
28
+
29
+ // Server errors (500)
30
+ INTERNAL_ERROR: 'INTERNAL_ERROR',
31
+ INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
32
+ DATABASE_ERROR: 'DATABASE_ERROR',
33
+ EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',
34
+
35
+ // Service unavailable (503)
36
+ SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
37
+ MAINTENANCE_MODE: 'MAINTENANCE_MODE',
38
+ RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
39
+
40
+ // Plugin errors
41
+ PLUGIN_ERROR: 'PLUGIN_ERROR',
42
+ PLUGIN_NOT_FOUND: 'PLUGIN_NOT_FOUND',
43
+ PLUGIN_INITIALIZATION_ERROR: 'PLUGIN_INITIALIZATION_ERROR',
44
+
45
+ // Configuration errors
46
+ CONFIG_ERROR: 'CONFIG_ERROR',
47
+ INVALID_CONFIG: 'INVALID_CONFIG',
48
+ MISSING_CONFIG: 'MISSING_CONFIG',
49
+
50
+ // Build errors
51
+ BUILD_ERROR: 'BUILD_ERROR',
52
+ COMPILATION_ERROR: 'COMPILATION_ERROR',
53
+ BUNDLING_ERROR: 'BUNDLING_ERROR'
54
+ } as const
55
+
56
+ export type ErrorCode = typeof ERROR_CODES[keyof typeof ERROR_CODES]
57
+
58
+ export const getErrorMessage = (code: ErrorCode): string => {
59
+ const messages: Record<ErrorCode, string> = {
60
+ // Validation errors
61
+ VALIDATION_ERROR: 'Validation failed',
62
+ INVALID_INPUT: 'Invalid input provided',
63
+ MISSING_REQUIRED_FIELD: 'Required field is missing',
64
+ INVALID_FORMAT: 'Invalid format',
65
+
66
+ // Authentication errors
67
+ UNAUTHORIZED: 'Authentication required',
68
+ INVALID_TOKEN: 'Invalid authentication token',
69
+ TOKEN_EXPIRED: 'Authentication token has expired',
70
+ INVALID_CREDENTIALS: 'Invalid credentials provided',
71
+
72
+ // Authorization errors
73
+ FORBIDDEN: 'Access forbidden',
74
+ INSUFFICIENT_PERMISSIONS: 'Insufficient permissions',
75
+ ACCESS_DENIED: 'Access denied',
76
+
77
+ // Not found errors
78
+ NOT_FOUND: 'Resource not found',
79
+ RESOURCE_NOT_FOUND: 'Requested resource not found',
80
+ ENDPOINT_NOT_FOUND: 'API endpoint not found',
81
+
82
+ // Conflict errors
83
+ CONFLICT: 'Resource conflict',
84
+ RESOURCE_ALREADY_EXISTS: 'Resource already exists',
85
+ DUPLICATE_ENTRY: 'Duplicate entry',
86
+
87
+ // Server errors
88
+ INTERNAL_ERROR: 'Internal server error',
89
+ INTERNAL_SERVER_ERROR: 'Internal server error',
90
+ DATABASE_ERROR: 'Database operation failed',
91
+ EXTERNAL_SERVICE_ERROR: 'External service error',
92
+
93
+ // Service unavailable
94
+ SERVICE_UNAVAILABLE: 'Service temporarily unavailable',
95
+ MAINTENANCE_MODE: 'Service is under maintenance',
96
+ RATE_LIMIT_EXCEEDED: 'Rate limit exceeded',
97
+
98
+ // Plugin errors
99
+ PLUGIN_ERROR: 'Plugin error',
100
+ PLUGIN_NOT_FOUND: 'Plugin not found',
101
+ PLUGIN_INITIALIZATION_ERROR: 'Plugin initialization failed',
102
+
103
+ // Configuration errors
104
+ CONFIG_ERROR: 'Configuration error',
105
+ INVALID_CONFIG: 'Invalid configuration',
106
+ MISSING_CONFIG: 'Missing configuration',
107
+
108
+ // Build errors
109
+ BUILD_ERROR: 'Build error',
110
+ COMPILATION_ERROR: 'Compilation failed',
111
+ BUNDLING_ERROR: 'Bundling failed'
112
+ }
113
+
114
+ return messages[code] || 'Unknown error'
115
115
  }
@@ -21,7 +21,7 @@ export interface ErrorMetricsCollector {
21
21
 
22
22
  export interface ErrorRecoveryStrategy {
23
23
  canRecover(error: FluxStackError): boolean
24
- recover(error: FluxStackError, context: ErrorHandlerContext): Promise<any> | any
24
+ recover(error: FluxStackError, context: ErrorHandlerContext): Promise<ErrorSerializedResponse> | ErrorSerializedResponse
25
25
  }
26
26
 
27
27
  export interface ErrorHandlerOptions {
@@ -144,7 +144,7 @@ export class EnhancedErrorHandler {
144
144
  /**
145
145
  * Format stack trace to readable string (handles Bun CallSite objects)
146
146
  */
147
- private formatErrorStack(stack: any): string | undefined {
147
+ private formatErrorStack(stack: unknown): string | undefined {
148
148
  if (!stack) return undefined
149
149
 
150
150
  // If stack is already a string, return it
@@ -153,7 +153,7 @@ export class EnhancedErrorHandler {
153
153
  // If stack is an array of CallSite objects (Bun), format them
154
154
  if (Array.isArray(stack)) {
155
155
  return stack
156
- .map((site: any, index: number) => {
156
+ .map((site: { getFileName?: () => string; getLineNumber?: () => number; getColumnNumber?: () => number; getFunctionName?: () => string }, index: number) => {
157
157
  try {
158
158
  const fileName = site.getFileName?.() || 'unknown'
159
159
  const lineNumber = site.getLineNumber?.() || 0
@@ -193,10 +193,10 @@ export class EnhancedErrorHandler {
193
193
  }
194
194
 
195
195
  // Skip logging for Vite internal routes (even if NOT_FOUND logging is enabled)
196
- if (error.code === 'NOT_FOUND' && error.metadata?.path) {
196
+ if (error.code === 'NOT_FOUND' && typeof error.metadata?.path === 'string') {
197
197
  const path = error.metadata.path
198
- if (path.startsWith('/@') ||
199
- path.startsWith('/__vite') ||
198
+ if (path.startsWith('/@') ||
199
+ path.startsWith('/__vite') ||
200
200
  path.includes('/.vite/') ||
201
201
  path.endsWith('.js.map') ||
202
202
  path.endsWith('.css.map')) {
@@ -228,18 +228,20 @@ export class EnhancedErrorHandler {
228
228
  return response
229
229
  }
230
230
 
231
- private sanitizeErrorResponse(errorResponse: any): any {
231
+ private sanitizeErrorResponse(errorResponse: ErrorSerializedResponse['error']): ErrorSerializedResponse['error'] {
232
232
  const sanitized = { ...errorResponse }
233
-
233
+
234
234
  // Remove potentially sensitive fields in production
235
- if (sanitized.details) {
235
+ if (sanitized.details && typeof sanitized.details === 'object' && sanitized.details !== null) {
236
236
  // Remove sensitive fields from details
237
+ const details = sanitized.details as Record<string, unknown>
237
238
  const sensitiveFields = ['password', 'token', 'secret', 'key', 'credential']
238
239
  for (const field of sensitiveFields) {
239
- if (sanitized.details[field]) {
240
- sanitized.details[field] = '[REDACTED]'
240
+ if (details[field]) {
241
+ details[field] = '[REDACTED]'
241
242
  }
242
243
  }
244
+ sanitized.details = details
243
245
  }
244
246
 
245
247
  return sanitized
@@ -249,7 +251,7 @@ export class EnhancedErrorHandler {
249
251
  this.recoveryStrategies.push(strategy)
250
252
  }
251
253
 
252
- removeRecoveryStrategy(strategyClass: new (...args: any[]) => ErrorRecoveryStrategy): void {
254
+ removeRecoveryStrategy(strategyClass: new (...args: unknown[]) => ErrorRecoveryStrategy): void {
253
255
  this.recoveryStrategies = this.recoveryStrategies.filter(
254
256
  strategy => !(strategy instanceof strategyClass)
255
257
  )
@@ -289,12 +291,14 @@ export class RetryRecoveryStrategy implements ErrorRecoveryStrategy {
289
291
  ) {}
290
292
 
291
293
  canRecover(error: FluxStackError): boolean {
292
- return this.retryableCodes.includes(error.code) &&
293
- (!error.context?.retryCount || error.context.retryCount < this.maxRetries)
294
+ const ctx = error.context as Record<string, unknown> | undefined
295
+ return this.retryableCodes.includes(error.code) &&
296
+ (!ctx?.retryCount || (ctx.retryCount as number) < this.maxRetries)
294
297
  }
295
298
 
296
- async recover(error: FluxStackError, context: ErrorHandlerContext): Promise<any> {
297
- const retryCount = (error.context?.retryCount || 0) + 1
299
+ async recover(error: FluxStackError, context: ErrorHandlerContext): Promise<ErrorSerializedResponse> {
300
+ const ctx = error.context as Record<string, unknown> | undefined
301
+ const retryCount = ((ctx?.retryCount as number) || 0) + 1
298
302
 
299
303
  context.logger.info('Attempting error recovery', {
300
304
  errorCode: error.code,
@@ -313,7 +317,7 @@ export class RetryRecoveryStrategy implements ErrorRecoveryStrategy {
313
317
 
314
318
  export class FallbackRecoveryStrategy implements ErrorRecoveryStrategy {
315
319
  constructor(
316
- private fallbackResponse: any,
320
+ private fallbackResponse: unknown,
317
321
  private applicableCodes: string[] = ['EXTERNAL_SERVICE_ERROR']
318
322
  ) {}
319
323
 
@@ -321,15 +325,21 @@ export class FallbackRecoveryStrategy implements ErrorRecoveryStrategy {
321
325
  return this.applicableCodes.includes(error.code)
322
326
  }
323
327
 
324
- recover(error: FluxStackError, context: ErrorHandlerContext): any {
328
+ recover(error: FluxStackError, context: ErrorHandlerContext): ErrorSerializedResponse {
325
329
  context.logger.info('Using fallback recovery', {
326
330
  errorCode: error.code,
327
331
  correlationId: error.metadata.correlationId
328
332
  })
329
333
 
330
334
  return {
331
- data: this.fallbackResponse,
332
- warning: 'Fallback data provided due to service unavailability'
335
+ error: {
336
+ message: 'Fallback data provided due to service unavailability',
337
+ code: error.code,
338
+ statusCode: error.statusCode,
339
+ details: { fallback: this.fallbackResponse },
340
+ timestamp: new Date().toISOString(),
341
+ correlationId: error.metadata.correlationId as string | undefined
342
+ }
333
343
  }
334
344
  }
335
345
  }