create-fluxstack 1.0.13 → 1.0.14

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 (214) hide show
  1. package/.env.example +29 -29
  2. package/app/client/README.md +69 -69
  3. package/app/client/index.html +14 -13
  4. package/app/client/src/App.tsx +157 -524
  5. package/app/client/src/components/ErrorBoundary.tsx +107 -0
  6. package/app/client/src/components/ErrorDisplay.css +365 -0
  7. package/app/client/src/components/ErrorDisplay.tsx +258 -0
  8. package/app/client/src/components/FluxStackConfig.tsx +1321 -0
  9. package/app/client/src/components/HybridLiveCounter.tsx +140 -0
  10. package/app/client/src/components/LiveClock.tsx +286 -0
  11. package/app/client/src/components/MainLayout.tsx +390 -0
  12. package/app/client/src/components/SidebarNavigation.tsx +391 -0
  13. package/app/client/src/components/StateDemo.tsx +178 -0
  14. package/app/client/src/components/SystemMonitor.tsx +1038 -0
  15. package/app/client/src/components/Teste.tsx +104 -0
  16. package/app/client/src/components/UserProfile.tsx +809 -0
  17. package/app/client/src/hooks/useAuth.ts +39 -0
  18. package/app/client/src/hooks/useNotifications.ts +56 -0
  19. package/app/client/src/lib/eden-api.ts +189 -53
  20. package/app/client/src/lib/errors.ts +340 -0
  21. package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
  22. package/app/client/src/lib/index.ts +45 -0
  23. package/app/client/src/main.tsx +3 -2
  24. package/app/client/src/pages/ApiDocs.tsx +182 -0
  25. package/app/client/src/pages/Demo.tsx +174 -0
  26. package/app/client/src/pages/HybridLive.tsx +263 -0
  27. package/app/client/src/pages/Overview.tsx +155 -0
  28. package/app/client/src/store/README.md +43 -0
  29. package/app/client/src/store/index.ts +16 -0
  30. package/app/client/src/store/slices/uiSlice.ts +151 -0
  31. package/app/client/src/store/slices/userSlice.ts +161 -0
  32. package/app/client/src/test/README.md +257 -0
  33. package/app/client/src/test/setup.ts +70 -0
  34. package/app/client/src/test/types.ts +12 -0
  35. package/app/client/src/vite-env.d.ts +1 -1
  36. package/app/client/tsconfig.app.json +44 -43
  37. package/app/client/tsconfig.json +7 -7
  38. package/app/client/tsconfig.node.json +25 -25
  39. package/app/client/zustand-setup.md +65 -0
  40. package/app/server/controllers/users.controller.ts +68 -68
  41. package/app/server/index.ts +9 -1
  42. package/app/server/live/CounterComponent.ts +191 -0
  43. package/app/server/live/FluxStackConfig.ts +529 -0
  44. package/app/server/live/LiveClockComponent.ts +214 -0
  45. package/app/server/live/SidebarNavigation.ts +156 -0
  46. package/app/server/live/SystemMonitor.ts +594 -0
  47. package/app/server/live/SystemMonitorIntegration.ts +151 -0
  48. package/app/server/live/TesteComponent.ts +87 -0
  49. package/app/server/live/UserProfileComponent.ts +135 -0
  50. package/app/server/live/register-components.ts +28 -0
  51. package/app/server/middleware/auth.ts +136 -0
  52. package/app/server/middleware/errorHandling.ts +250 -0
  53. package/app/server/middleware/index.ts +10 -0
  54. package/app/server/middleware/rateLimit.ts +193 -0
  55. package/app/server/middleware/requestLogging.ts +215 -0
  56. package/app/server/middleware/validation.ts +270 -0
  57. package/app/server/routes/index.ts +14 -2
  58. package/app/server/routes/upload.ts +92 -0
  59. package/app/server/routes/users.routes.ts +2 -9
  60. package/app/server/services/NotificationService.ts +302 -0
  61. package/app/server/services/UserService.ts +222 -0
  62. package/app/server/services/index.ts +46 -0
  63. package/core/cli/commands/plugin-deps.ts +263 -0
  64. package/core/cli/generators/README.md +339 -0
  65. package/core/cli/generators/component.ts +770 -0
  66. package/core/cli/generators/controller.ts +299 -0
  67. package/core/cli/generators/index.ts +144 -0
  68. package/core/cli/generators/interactive.ts +228 -0
  69. package/core/cli/generators/prompts.ts +83 -0
  70. package/core/cli/generators/route.ts +513 -0
  71. package/core/cli/generators/service.ts +465 -0
  72. package/core/cli/generators/template-engine.ts +154 -0
  73. package/core/cli/generators/types.ts +71 -0
  74. package/core/cli/generators/utils.ts +192 -0
  75. package/core/cli/index.ts +69 -0
  76. package/core/cli/plugin-discovery.ts +16 -85
  77. package/core/client/fluxstack.ts +17 -0
  78. package/core/client/hooks/index.ts +7 -0
  79. package/core/client/hooks/state-validator.ts +130 -0
  80. package/core/client/hooks/useAuth.ts +49 -0
  81. package/core/client/hooks/useChunkedUpload.ts +258 -0
  82. package/core/client/hooks/useHybridLiveComponent.ts +967 -0
  83. package/core/client/hooks/useWebSocket.ts +373 -0
  84. package/core/client/index.ts +47 -0
  85. package/core/client/state/createStore.ts +193 -0
  86. package/core/client/state/index.ts +15 -0
  87. package/core/config/env-dynamic.ts +1 -1
  88. package/core/config/env.ts +2 -1
  89. package/core/config/runtime-config.ts +3 -3
  90. package/core/config/schema.ts +84 -49
  91. package/core/framework/server.ts +30 -0
  92. package/core/index.ts +25 -0
  93. package/core/live/ComponentRegistry.ts +399 -0
  94. package/core/live/types.ts +164 -0
  95. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
  96. package/core/plugins/built-in/live-components/index.ts +27 -0
  97. package/core/plugins/built-in/logger/index.ts +1 -1
  98. package/core/plugins/built-in/monitoring/index.ts +1 -1
  99. package/core/plugins/built-in/static/index.ts +1 -1
  100. package/core/plugins/built-in/swagger/index.ts +1 -1
  101. package/core/plugins/built-in/vite/index.ts +1 -1
  102. package/core/plugins/dependency-manager.ts +384 -0
  103. package/core/plugins/index.ts +5 -1
  104. package/core/plugins/manager.ts +7 -3
  105. package/core/plugins/registry.ts +88 -10
  106. package/core/plugins/types.ts +11 -11
  107. package/core/server/framework.ts +43 -0
  108. package/core/server/index.ts +11 -1
  109. package/core/server/live/ComponentRegistry.ts +1017 -0
  110. package/core/server/live/FileUploadManager.ts +272 -0
  111. package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
  112. package/core/server/live/SingleConnectionManager.ts +0 -0
  113. package/core/server/live/StateSignature.ts +644 -0
  114. package/core/server/live/WebSocketConnectionManager.ts +688 -0
  115. package/core/server/live/websocket-plugin.ts +435 -0
  116. package/core/server/middleware/errorHandling.ts +141 -0
  117. package/core/server/middleware/index.ts +16 -0
  118. package/core/server/plugins/static-files-plugin.ts +232 -0
  119. package/core/server/services/BaseService.ts +95 -0
  120. package/core/server/services/ServiceContainer.ts +144 -0
  121. package/core/server/services/index.ts +9 -0
  122. package/core/templates/create-project.ts +46 -2
  123. package/core/testing/index.ts +10 -0
  124. package/core/testing/setup.ts +74 -0
  125. package/core/types/build.ts +38 -14
  126. package/core/types/types.ts +319 -0
  127. package/core/utils/env-runtime.ts +7 -0
  128. package/core/utils/errors/handlers.ts +264 -39
  129. package/core/utils/errors/index.ts +528 -18
  130. package/core/utils/errors/middleware.ts +114 -0
  131. package/core/utils/logger/formatters.ts +222 -0
  132. package/core/utils/logger/index.ts +167 -48
  133. package/core/utils/logger/middleware.ts +253 -0
  134. package/core/utils/logger/performance.ts +384 -0
  135. package/core/utils/logger/transports.ts +365 -0
  136. package/create-fluxstack.ts +296 -296
  137. package/fluxstack.config.ts +17 -1
  138. package/package-template.json +66 -66
  139. package/package.json +31 -6
  140. package/public/README.md +16 -0
  141. package/vite.config.ts +29 -14
  142. package/.claude/settings.local.json +0 -74
  143. package/.github/workflows/ci-build-tests.yml +0 -480
  144. package/.github/workflows/dependency-management.yml +0 -324
  145. package/.github/workflows/release-validation.yml +0 -355
  146. package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
  147. package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
  148. package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
  149. package/CLAUDE.md +0 -200
  150. package/Dockerfile +0 -58
  151. package/Dockerfile.backend +0 -52
  152. package/Dockerfile.frontend +0 -54
  153. package/README-Docker.md +0 -85
  154. package/ai-context/00-QUICK-START.md +0 -86
  155. package/ai-context/README.md +0 -88
  156. package/ai-context/development/eden-treaty-guide.md +0 -362
  157. package/ai-context/development/patterns.md +0 -382
  158. package/ai-context/development/plugins-guide.md +0 -572
  159. package/ai-context/examples/crud-complete.md +0 -626
  160. package/ai-context/project/architecture.md +0 -399
  161. package/ai-context/project/overview.md +0 -213
  162. package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
  163. package/ai-context/recent-changes/type-inference-fix.md +0 -223
  164. package/ai-context/reference/environment-vars.md +0 -384
  165. package/ai-context/reference/troubleshooting.md +0 -407
  166. package/app/client/src/components/TestPage.tsx +0 -453
  167. package/bun.lock +0 -1063
  168. package/bunfig.toml +0 -16
  169. package/core/__tests__/integration.test.ts +0 -227
  170. package/core/build/index.ts +0 -186
  171. package/core/config/__tests__/config-loader.test.ts +0 -554
  172. package/core/config/__tests__/config-merger.test.ts +0 -657
  173. package/core/config/__tests__/env-converter.test.ts +0 -372
  174. package/core/config/__tests__/env-processor.test.ts +0 -431
  175. package/core/config/__tests__/env.test.ts +0 -452
  176. package/core/config/__tests__/integration.test.ts +0 -418
  177. package/core/config/__tests__/loader.test.ts +0 -331
  178. package/core/config/__tests__/schema.test.ts +0 -129
  179. package/core/config/__tests__/validator.test.ts +0 -318
  180. package/core/framework/__tests__/server.test.ts +0 -233
  181. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  182. package/core/plugins/__tests__/manager.test.ts +0 -398
  183. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  184. package/core/plugins/__tests__/registry.test.ts +0 -335
  185. package/core/utils/__tests__/errors.test.ts +0 -139
  186. package/core/utils/__tests__/helpers.test.ts +0 -297
  187. package/core/utils/__tests__/logger.test.ts +0 -141
  188. package/create-test-app.ts +0 -156
  189. package/docker-compose.microservices.yml +0 -75
  190. package/docker-compose.simple.yml +0 -57
  191. package/docker-compose.yml +0 -71
  192. package/eslint.config.js +0 -23
  193. package/flux-cli.ts +0 -214
  194. package/nginx-lb.conf +0 -37
  195. package/publish.sh +0 -63
  196. package/run-clean.ts +0 -26
  197. package/run-env-tests.ts +0 -313
  198. package/tailwind.config.js +0 -34
  199. package/tests/__mocks__/api.ts +0 -56
  200. package/tests/fixtures/users.ts +0 -69
  201. package/tests/integration/api/users.routes.test.ts +0 -221
  202. package/tests/setup.ts +0 -29
  203. package/tests/unit/app/client/App-simple.test.tsx +0 -56
  204. package/tests/unit/app/client/App.test.tsx.skip +0 -237
  205. package/tests/unit/app/client/eden-api.test.ts +0 -186
  206. package/tests/unit/app/client/simple.test.tsx +0 -23
  207. package/tests/unit/app/controllers/users.controller.test.ts +0 -150
  208. package/tests/unit/core/create-project.test.ts.skip +0 -95
  209. package/tests/unit/core/framework.test.ts +0 -144
  210. package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
  211. package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
  212. package/tests/utils/test-helpers.ts +0 -61
  213. package/vitest.config.ts +0 -50
  214. package/workspace.json +0 -6
@@ -1,14 +1,41 @@
1
+ export interface ErrorMetadata {
2
+ correlationId?: string
3
+ userId?: string
4
+ requestId?: string
5
+ userAgent?: string
6
+ ip?: string
7
+ [key: string]: any
8
+ }
9
+
10
+ export interface ErrorSerializedResponse {
11
+ error: {
12
+ message: string
13
+ code: string
14
+ statusCode: number
15
+ details?: any
16
+ timestamp: string
17
+ correlationId?: string
18
+ stack?: string
19
+ }
20
+ }
21
+
1
22
  export class FluxStackError extends Error {
2
23
  public readonly code: string
3
24
  public readonly statusCode: number
4
25
  public readonly context?: any
5
26
  public readonly timestamp: Date
27
+ public readonly metadata: ErrorMetadata
28
+ public readonly isOperational: boolean
29
+ public readonly userMessage?: string
6
30
 
7
31
  constructor(
8
32
  message: string,
9
33
  code: string,
10
34
  statusCode: number = 500,
11
- context?: any
35
+ context?: any,
36
+ metadata: ErrorMetadata = {},
37
+ isOperational: boolean = true,
38
+ userMessage?: string
12
39
  ) {
13
40
  super(message)
14
41
  this.name = 'FluxStackError'
@@ -16,6 +43,14 @@ export class FluxStackError extends Error {
16
43
  this.statusCode = statusCode
17
44
  this.context = context
18
45
  this.timestamp = new Date()
46
+ this.metadata = metadata
47
+ this.isOperational = isOperational
48
+ this.userMessage = userMessage
49
+
50
+ // Maintain proper stack trace
51
+ if (Error.captureStackTrace) {
52
+ Error.captureStackTrace(this, FluxStackError)
53
+ }
19
54
  }
20
55
 
21
56
  toJSON() {
@@ -26,56 +61,531 @@ export class FluxStackError extends Error {
26
61
  statusCode: this.statusCode,
27
62
  context: this.context,
28
63
  timestamp: this.timestamp,
64
+ metadata: this.metadata,
65
+ isOperational: this.isOperational,
66
+ userMessage: this.userMessage,
29
67
  stack: this.stack
30
68
  }
31
69
  }
70
+
71
+ toResponse(isDevelopment: boolean = false): ErrorSerializedResponse {
72
+ return {
73
+ error: {
74
+ message: this.userMessage || this.message,
75
+ code: this.code,
76
+ statusCode: this.statusCode,
77
+ ...(this.context && { details: this.context }),
78
+ timestamp: this.timestamp.toISOString(),
79
+ ...(this.metadata.correlationId && { correlationId: this.metadata.correlationId }),
80
+ ...(isDevelopment && { stack: this.stack })
81
+ }
82
+ }
83
+ }
84
+
85
+ withMetadata(metadata: ErrorMetadata): FluxStackError {
86
+ return new FluxStackError(
87
+ this.message,
88
+ this.code,
89
+ this.statusCode,
90
+ this.context,
91
+ { ...this.metadata, ...metadata },
92
+ this.isOperational,
93
+ this.userMessage
94
+ )
95
+ }
96
+
97
+ withCorrelationId(correlationId: string): FluxStackError {
98
+ return this.withMetadata({ correlationId })
99
+ }
32
100
  }
33
101
 
102
+ // Validation Errors (400)
34
103
  export class ValidationError extends FluxStackError {
35
- constructor(message: string, context?: any) {
36
- super(message, 'VALIDATION_ERROR', 400, context)
104
+ constructor(message: string, context?: any, metadata?: ErrorMetadata) {
105
+ super(
106
+ message,
107
+ 'VALIDATION_ERROR',
108
+ 400,
109
+ context,
110
+ metadata,
111
+ true,
112
+ 'Please check your input and try again'
113
+ )
37
114
  this.name = 'ValidationError'
38
115
  }
39
116
  }
40
117
 
41
- export class NotFoundError extends FluxStackError {
42
- constructor(resource: string, context?: any) {
43
- super(`${resource} not found`, 'NOT_FOUND', 404, context)
44
- this.name = 'NotFoundError'
118
+ export class InvalidInputError extends FluxStackError {
119
+ constructor(field: string, value?: any, metadata?: ErrorMetadata) {
120
+ super(
121
+ `Invalid input for field: ${field}`,
122
+ 'INVALID_INPUT',
123
+ 400,
124
+ { field, value },
125
+ metadata,
126
+ true,
127
+ `The value provided for ${field} is not valid`
128
+ )
129
+ this.name = 'InvalidInputError'
45
130
  }
46
131
  }
47
132
 
133
+ export class MissingRequiredFieldError extends FluxStackError {
134
+ constructor(field: string, metadata?: ErrorMetadata) {
135
+ super(
136
+ `Missing required field: ${field}`,
137
+ 'MISSING_REQUIRED_FIELD',
138
+ 400,
139
+ { field },
140
+ metadata,
141
+ true,
142
+ `The field ${field} is required`
143
+ )
144
+ this.name = 'MissingRequiredFieldError'
145
+ }
146
+ }
147
+
148
+ // Authentication Errors (401)
48
149
  export class UnauthorizedError extends FluxStackError {
49
- constructor(message: string = 'Unauthorized', context?: any) {
50
- super(message, 'UNAUTHORIZED', 401, context)
150
+ constructor(message: string = 'Authentication required', context?: any, metadata?: ErrorMetadata) {
151
+ super(
152
+ message,
153
+ 'UNAUTHORIZED',
154
+ 401,
155
+ context,
156
+ metadata,
157
+ true,
158
+ 'Please log in to access this resource'
159
+ )
51
160
  this.name = 'UnauthorizedError'
52
161
  }
53
162
  }
54
163
 
164
+ export class InvalidTokenError extends FluxStackError {
165
+ constructor(metadata?: ErrorMetadata) {
166
+ super(
167
+ 'Invalid authentication token',
168
+ 'INVALID_TOKEN',
169
+ 401,
170
+ undefined,
171
+ metadata,
172
+ true,
173
+ 'Your session has expired. Please log in again'
174
+ )
175
+ this.name = 'InvalidTokenError'
176
+ }
177
+ }
178
+
179
+ export class TokenExpiredError extends FluxStackError {
180
+ constructor(metadata?: ErrorMetadata) {
181
+ super(
182
+ 'Authentication token has expired',
183
+ 'TOKEN_EXPIRED',
184
+ 401,
185
+ undefined,
186
+ metadata,
187
+ true,
188
+ 'Your session has expired. Please log in again'
189
+ )
190
+ this.name = 'TokenExpiredError'
191
+ }
192
+ }
193
+
194
+ // Authorization Errors (403)
55
195
  export class ForbiddenError extends FluxStackError {
56
- constructor(message: string = 'Forbidden', context?: any) {
57
- super(message, 'FORBIDDEN', 403, context)
196
+ constructor(message: string = 'Access forbidden', context?: any, metadata?: ErrorMetadata) {
197
+ super(
198
+ message,
199
+ 'FORBIDDEN',
200
+ 403,
201
+ context,
202
+ metadata,
203
+ true,
204
+ 'You do not have permission to access this resource'
205
+ )
58
206
  this.name = 'ForbiddenError'
59
207
  }
60
208
  }
61
209
 
210
+ export class InsufficientPermissionsError extends FluxStackError {
211
+ constructor(requiredPermission: string, metadata?: ErrorMetadata) {
212
+ super(
213
+ `Insufficient permissions: ${requiredPermission} required`,
214
+ 'INSUFFICIENT_PERMISSIONS',
215
+ 403,
216
+ { requiredPermission },
217
+ metadata,
218
+ true,
219
+ 'You do not have the required permissions for this action'
220
+ )
221
+ this.name = 'InsufficientPermissionsError'
222
+ }
223
+ }
224
+
225
+ // Not Found Errors (404)
226
+ export class NotFoundError extends FluxStackError {
227
+ constructor(resource: string, context?: any, metadata?: ErrorMetadata) {
228
+ super(
229
+ `${resource} not found`,
230
+ 'NOT_FOUND',
231
+ 404,
232
+ context,
233
+ metadata,
234
+ true,
235
+ 'The requested resource could not be found'
236
+ )
237
+ this.name = 'NotFoundError'
238
+ }
239
+ }
240
+
241
+ export class ResourceNotFoundError extends FluxStackError {
242
+ constructor(resourceType: string, identifier: string, metadata?: ErrorMetadata) {
243
+ super(
244
+ `${resourceType} with identifier '${identifier}' not found`,
245
+ 'RESOURCE_NOT_FOUND',
246
+ 404,
247
+ { resourceType, identifier },
248
+ metadata,
249
+ true,
250
+ `The requested ${resourceType.toLowerCase()} could not be found`
251
+ )
252
+ this.name = 'ResourceNotFoundError'
253
+ }
254
+ }
255
+
256
+ export class EndpointNotFoundError extends FluxStackError {
257
+ constructor(method: string, path: string, metadata?: ErrorMetadata) {
258
+ super(
259
+ `Endpoint not found: ${method} ${path}`,
260
+ 'ENDPOINT_NOT_FOUND',
261
+ 404,
262
+ { method, path },
263
+ metadata,
264
+ true,
265
+ 'The requested API endpoint does not exist'
266
+ )
267
+ this.name = 'EndpointNotFoundError'
268
+ }
269
+ }
270
+
271
+ // Conflict Errors (409)
62
272
  export class ConflictError extends FluxStackError {
63
- constructor(message: string, context?: any) {
64
- super(message, 'CONFLICT', 409, context)
273
+ constructor(message: string, context?: any, metadata?: ErrorMetadata) {
274
+ super(
275
+ message,
276
+ 'CONFLICT',
277
+ 409,
278
+ context,
279
+ metadata,
280
+ true,
281
+ 'There was a conflict with the current state of the resource'
282
+ )
65
283
  this.name = 'ConflictError'
66
284
  }
67
285
  }
68
286
 
287
+ export class ResourceAlreadyExistsError extends FluxStackError {
288
+ constructor(resourceType: string, identifier: string, metadata?: ErrorMetadata) {
289
+ super(
290
+ `${resourceType} with identifier '${identifier}' already exists`,
291
+ 'RESOURCE_ALREADY_EXISTS',
292
+ 409,
293
+ { resourceType, identifier },
294
+ metadata,
295
+ true,
296
+ `A ${resourceType.toLowerCase()} with that identifier already exists`
297
+ )
298
+ this.name = 'ResourceAlreadyExistsError'
299
+ }
300
+ }
301
+
302
+ // Rate Limiting Errors (429)
303
+ export class RateLimitExceededError extends FluxStackError {
304
+ constructor(limit: number, windowMs: number, metadata?: ErrorMetadata) {
305
+ super(
306
+ `Rate limit exceeded: ${limit} requests per ${windowMs}ms`,
307
+ 'RATE_LIMIT_EXCEEDED',
308
+ 429,
309
+ { limit, windowMs },
310
+ metadata,
311
+ true,
312
+ 'Too many requests. Please try again later'
313
+ )
314
+ this.name = 'RateLimitExceededError'
315
+ }
316
+ }
317
+
318
+ // Server Errors (500)
69
319
  export class InternalServerError extends FluxStackError {
70
- constructor(message: string = 'Internal server error', context?: any) {
71
- super(message, 'INTERNAL_SERVER_ERROR', 500, context)
320
+ constructor(message: string = 'Internal server error', context?: any, metadata?: ErrorMetadata) {
321
+ super(
322
+ message,
323
+ 'INTERNAL_SERVER_ERROR',
324
+ 500,
325
+ context,
326
+ metadata,
327
+ false,
328
+ 'An unexpected error occurred. Please try again later'
329
+ )
72
330
  this.name = 'InternalServerError'
73
331
  }
74
332
  }
75
333
 
334
+ export class DatabaseError extends FluxStackError {
335
+ constructor(operation: string, details?: any, metadata?: ErrorMetadata) {
336
+ super(
337
+ `Database operation failed: ${operation}`,
338
+ 'DATABASE_ERROR',
339
+ 500,
340
+ { operation, details },
341
+ metadata,
342
+ false,
343
+ 'A database error occurred. Please try again later'
344
+ )
345
+ this.name = 'DatabaseError'
346
+ }
347
+ }
348
+
349
+ export class ExternalServiceError extends FluxStackError {
350
+ constructor(service: string, details?: any, metadata?: ErrorMetadata) {
351
+ super(
352
+ `External service error: ${service}`,
353
+ 'EXTERNAL_SERVICE_ERROR',
354
+ 500,
355
+ { service, details },
356
+ metadata,
357
+ false,
358
+ 'An external service is currently unavailable. Please try again later'
359
+ )
360
+ this.name = 'ExternalServiceError'
361
+ }
362
+ }
363
+
364
+ // Service Unavailable Errors (503)
76
365
  export class ServiceUnavailableError extends FluxStackError {
77
- constructor(message: string = 'Service unavailable', context?: any) {
78
- super(message, 'SERVICE_UNAVAILABLE', 503, context)
366
+ constructor(message: string = 'Service unavailable', context?: any, metadata?: ErrorMetadata) {
367
+ super(
368
+ message,
369
+ 'SERVICE_UNAVAILABLE',
370
+ 503,
371
+ context,
372
+ metadata,
373
+ true,
374
+ 'The service is temporarily unavailable. Please try again later'
375
+ )
79
376
  this.name = 'ServiceUnavailableError'
80
377
  }
81
- }
378
+ }
379
+
380
+ export class MaintenanceModeError extends FluxStackError {
381
+ constructor(estimatedDuration?: string, metadata?: ErrorMetadata) {
382
+ super(
383
+ 'Service is under maintenance',
384
+ 'MAINTENANCE_MODE',
385
+ 503,
386
+ { estimatedDuration },
387
+ metadata,
388
+ true,
389
+ estimatedDuration
390
+ ? `The service is under maintenance. Expected to be back ${estimatedDuration}`
391
+ : 'The service is under maintenance. Please try again later'
392
+ )
393
+ this.name = 'MaintenanceModeError'
394
+ }
395
+ }
396
+
397
+ // Plugin Errors
398
+ export class PluginError extends FluxStackError {
399
+ constructor(pluginName: string, message: string, context?: any, metadata?: ErrorMetadata) {
400
+ super(
401
+ `Plugin error in ${pluginName}: ${message}`,
402
+ 'PLUGIN_ERROR',
403
+ 500,
404
+ { pluginName, ...context },
405
+ metadata,
406
+ false,
407
+ 'A plugin error occurred. Please contact support if this persists'
408
+ )
409
+ this.name = 'PluginError'
410
+ }
411
+ }
412
+
413
+ export class PluginNotFoundError extends FluxStackError {
414
+ constructor(pluginName: string, metadata?: ErrorMetadata) {
415
+ super(
416
+ `Plugin not found: ${pluginName}`,
417
+ 'PLUGIN_NOT_FOUND',
418
+ 404,
419
+ { pluginName },
420
+ metadata,
421
+ true,
422
+ `The requested plugin '${pluginName}' is not available`
423
+ )
424
+ this.name = 'PluginNotFoundError'
425
+ }
426
+ }
427
+
428
+ // Configuration Errors
429
+ export class ConfigError extends FluxStackError {
430
+ constructor(message: string, context?: any, metadata?: ErrorMetadata) {
431
+ super(
432
+ `Configuration error: ${message}`,
433
+ 'CONFIG_ERROR',
434
+ 500,
435
+ context,
436
+ metadata,
437
+ false,
438
+ 'A configuration error occurred. Please check your settings'
439
+ )
440
+ this.name = 'ConfigError'
441
+ }
442
+ }
443
+
444
+ export class InvalidConfigError extends FluxStackError {
445
+ constructor(field: string, value?: any, metadata?: ErrorMetadata) {
446
+ super(
447
+ `Invalid configuration for field: ${field}`,
448
+ 'INVALID_CONFIG',
449
+ 500,
450
+ { field, value },
451
+ metadata,
452
+ false,
453
+ 'Invalid configuration detected. Please check your settings'
454
+ )
455
+ this.name = 'InvalidConfigError'
456
+ }
457
+ }
458
+
459
+ // Build Errors
460
+ export class BuildError extends FluxStackError {
461
+ constructor(message: string, context?: any, metadata?: ErrorMetadata) {
462
+ super(
463
+ `Build error: ${message}`,
464
+ 'BUILD_ERROR',
465
+ 500,
466
+ context,
467
+ metadata,
468
+ false,
469
+ 'A build error occurred'
470
+ )
471
+ this.name = 'BuildError'
472
+ }
473
+ }
474
+
475
+ export class CompilationError extends FluxStackError {
476
+ constructor(file: string, details?: any, metadata?: ErrorMetadata) {
477
+ super(
478
+ `Compilation failed for file: ${file}`,
479
+ 'COMPILATION_ERROR',
480
+ 500,
481
+ { file, details },
482
+ metadata,
483
+ false,
484
+ 'Compilation failed'
485
+ )
486
+ this.name = 'CompilationError'
487
+ }
488
+ }
489
+
490
+ // Utility functions for error handling
491
+ export const isFluxStackError = (error: any): error is FluxStackError => {
492
+ return error instanceof FluxStackError
493
+ }
494
+
495
+ export const isOperationalError = (error: any): boolean => {
496
+ return isFluxStackError(error) && error.isOperational
497
+ }
498
+
499
+ export const createErrorFromCode = (
500
+ code: string,
501
+ message?: string,
502
+ context?: any,
503
+ metadata?: ErrorMetadata
504
+ ): FluxStackError => {
505
+ switch (code) {
506
+ case 'VALIDATION_ERROR':
507
+ return new ValidationError(message || 'Validation failed', context, metadata)
508
+ case 'INVALID_INPUT':
509
+ return new InvalidInputError(context?.field || 'unknown', context?.value, metadata)
510
+ case 'MISSING_REQUIRED_FIELD':
511
+ return new MissingRequiredFieldError(context?.field || 'unknown', metadata)
512
+ case 'UNAUTHORIZED':
513
+ return new UnauthorizedError(message, context, metadata)
514
+ case 'INVALID_TOKEN':
515
+ return new InvalidTokenError(metadata)
516
+ case 'TOKEN_EXPIRED':
517
+ return new TokenExpiredError(metadata)
518
+ case 'FORBIDDEN':
519
+ return new ForbiddenError(message, context, metadata)
520
+ case 'INSUFFICIENT_PERMISSIONS':
521
+ return new InsufficientPermissionsError(context?.requiredPermission || 'unknown', metadata)
522
+ case 'NOT_FOUND':
523
+ return new NotFoundError(context?.resource || 'Resource', context, metadata)
524
+ case 'RESOURCE_NOT_FOUND':
525
+ return new ResourceNotFoundError(
526
+ context?.resourceType || 'Resource',
527
+ context?.identifier || 'unknown',
528
+ metadata
529
+ )
530
+ case 'ENDPOINT_NOT_FOUND':
531
+ return new EndpointNotFoundError(
532
+ context?.method || 'GET',
533
+ context?.path || '/unknown',
534
+ metadata
535
+ )
536
+ case 'CONFLICT':
537
+ return new ConflictError(message || 'Resource conflict', context, metadata)
538
+ case 'RESOURCE_ALREADY_EXISTS':
539
+ return new ResourceAlreadyExistsError(
540
+ context?.resourceType || 'Resource',
541
+ context?.identifier || 'unknown',
542
+ metadata
543
+ )
544
+ case 'RATE_LIMIT_EXCEEDED':
545
+ return new RateLimitExceededError(
546
+ context?.limit || 100,
547
+ context?.windowMs || 60000,
548
+ metadata
549
+ )
550
+ case 'INTERNAL_SERVER_ERROR':
551
+ return new InternalServerError(message, context, metadata)
552
+ case 'DATABASE_ERROR':
553
+ return new DatabaseError(context?.operation || 'unknown', context?.details, metadata)
554
+ case 'EXTERNAL_SERVICE_ERROR':
555
+ return new ExternalServiceError(context?.service || 'unknown', context?.details, metadata)
556
+ case 'SERVICE_UNAVAILABLE':
557
+ return new ServiceUnavailableError(message, context, metadata)
558
+ case 'MAINTENANCE_MODE':
559
+ return new MaintenanceModeError(context?.estimatedDuration, metadata)
560
+ case 'PLUGIN_ERROR':
561
+ return new PluginError(
562
+ context?.pluginName || 'unknown',
563
+ message || 'Plugin error',
564
+ context,
565
+ metadata
566
+ )
567
+ case 'PLUGIN_NOT_FOUND':
568
+ return new PluginNotFoundError(context?.pluginName || 'unknown', metadata)
569
+ case 'CONFIG_ERROR':
570
+ return new ConfigError(message || 'Configuration error', context, metadata)
571
+ case 'INVALID_CONFIG':
572
+ return new InvalidConfigError(context?.field || 'unknown', context?.value, metadata)
573
+ case 'BUILD_ERROR':
574
+ return new BuildError(message || 'Build error', context, metadata)
575
+ case 'COMPILATION_ERROR':
576
+ return new CompilationError(context?.file || 'unknown', context?.details, metadata)
577
+ default:
578
+ return new FluxStackError(message || 'Unknown error', code, 500, context, metadata)
579
+ }
580
+ }
581
+
582
+ export const wrapError = (error: Error, metadata?: ErrorMetadata): FluxStackError => {
583
+ if (isFluxStackError(error)) {
584
+ return metadata ? error.withMetadata(metadata) : error
585
+ }
586
+
587
+ return new InternalServerError(error.message, { originalError: error.name }, metadata)
588
+ }
589
+
590
+ // Re-export error codes for convenience
591
+ export { ERROR_CODES, type ErrorCode, getErrorMessage } from './codes'