@stacksjs/bun-router 0.0.17 → 0.0.18

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 (146) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/container/service-provider.d.ts +3 -3
  3. package/dist/development/performance-profiler.d.ts +3 -3
  4. package/dist/development/route-debugger.d.ts +1 -1
  5. package/dist/development/route-inspector.d.ts +2 -2
  6. package/dist/observability/integration.d.ts +1 -1
  7. package/dist/response/macros.d.ts +1 -1
  8. package/dist/router/index.d.ts +7 -7
  9. package/dist/router/router.d.ts +0 -32
  10. package/dist/testing/performance-testing.d.ts +2 -2
  11. package/dist/testing/test-client.d.ts +1 -1
  12. package/dist/testing/websocket-testing.d.ts +1 -1
  13. package/package.json +2 -3
  14. package/src/auth.ts +0 -489
  15. package/src/cache/lru-cache.ts +0 -457
  16. package/src/cache/middleware-memoization.ts +0 -531
  17. package/src/cache/route-cache-warmer.ts +0 -486
  18. package/src/cache/sqlite-cache.ts +0 -783
  19. package/src/cache/streaming-cache.ts +0 -572
  20. package/src/cli/colors.ts +0 -29
  21. package/src/cli/index.ts +0 -287
  22. package/src/cli/middleware.ts +0 -291
  23. package/src/cli/openapi.ts +0 -407
  24. package/src/cli/router.ts +0 -188
  25. package/src/cli/routes.ts +0 -265
  26. package/src/cli/utils.ts +0 -531
  27. package/src/cli.ts +0 -5
  28. package/src/config.ts +0 -322
  29. package/src/container/container.ts +0 -786
  30. package/src/container/contextual-binding.ts +0 -606
  31. package/src/container/decorators.ts +0 -368
  32. package/src/container/index.ts +0 -49
  33. package/src/container/service-provider.ts +0 -596
  34. package/src/development/hot-reload.ts +0 -673
  35. package/src/development/index.ts +0 -499
  36. package/src/development/performance-profiler.ts +0 -717
  37. package/src/development/route-debugger.ts +0 -527
  38. package/src/development/route-inspector.ts +0 -749
  39. package/src/development/typescript-utilities.ts +0 -682
  40. package/src/docs.ts +0 -397
  41. package/src/errors/circuit-breaker.ts +0 -733
  42. package/src/errors/error-handler.ts +0 -569
  43. package/src/errors/error-reporting.ts +0 -672
  44. package/src/errors/exceptions.ts +0 -536
  45. package/src/errors/graceful-degradation.ts +0 -623
  46. package/src/errors/index.ts +0 -21
  47. package/src/errors/router-errors.ts +0 -632
  48. package/src/file-serving/static-files.ts +0 -718
  49. package/src/index.ts +0 -66
  50. package/src/middleware/auth.ts +0 -220
  51. package/src/middleware/content_security_policy.ts +0 -215
  52. package/src/middleware/cors.ts +0 -142
  53. package/src/middleware/csrf.ts +0 -166
  54. package/src/middleware/ddos_protection.ts +0 -279
  55. package/src/middleware/file_security.ts +0 -191
  56. package/src/middleware/file_upload.ts +0 -275
  57. package/src/middleware/helmet.ts +0 -268
  58. package/src/middleware/index.ts +0 -117
  59. package/src/middleware/input_validation.ts +0 -453
  60. package/src/middleware/json_body.ts +0 -37
  61. package/src/middleware/performance_alerting.ts +0 -540
  62. package/src/middleware/performance_dashboard.ts +0 -661
  63. package/src/middleware/performance_monitor.ts +0 -945
  64. package/src/middleware/pipeline.ts +0 -489
  65. package/src/middleware/rate_limit.ts +0 -251
  66. package/src/middleware/request_id.ts +0 -36
  67. package/src/middleware/request_signing.ts +0 -638
  68. package/src/middleware/request_tracer.ts +0 -653
  69. package/src/middleware/response_cache.ts +0 -778
  70. package/src/middleware/security.ts +0 -482
  71. package/src/middleware/security_suite.ts +0 -257
  72. package/src/middleware/session.ts +0 -91
  73. package/src/model-binding/index.ts +0 -18
  74. package/src/model-binding/model-middleware.ts +0 -425
  75. package/src/model-binding/model-registry.ts +0 -550
  76. package/src/model-binding.ts +0 -370
  77. package/src/model-resolver-factory.ts +0 -106
  78. package/src/observability/correlation.ts +0 -691
  79. package/src/observability/health-checks.ts +0 -729
  80. package/src/observability/index.ts +0 -184
  81. package/src/observability/integration.ts +0 -548
  82. package/src/observability/metrics.ts +0 -753
  83. package/src/observability/tracing.ts +0 -638
  84. package/src/optimization/bun-utilities.ts +0 -778
  85. package/src/query-builder-integration.ts +0 -137
  86. package/src/request/context.ts +0 -109
  87. package/src/request/enhanced-request.ts +0 -876
  88. package/src/request/macros.ts +0 -822
  89. package/src/response/macros.ts +0 -665
  90. package/src/response/response-factory.ts +0 -596
  91. package/src/router/api-routes.ts +0 -243
  92. package/src/router/file-based-routing.ts +0 -697
  93. package/src/router/file-streaming.ts +0 -383
  94. package/src/router/fluent-routing.ts +0 -866
  95. package/src/router/group-organization.ts +0 -229
  96. package/src/router/handler-resolver.ts +0 -327
  97. package/src/router/http-methods.ts +0 -407
  98. package/src/router/index.ts +0 -193
  99. package/src/router/middleware-groups.ts +0 -222
  100. package/src/router/middleware-integration.ts +0 -399
  101. package/src/router/middleware.ts +0 -234
  102. package/src/router/model-binding.ts +0 -215
  103. package/src/router/optimized-route-matching.ts +0 -302
  104. package/src/router/route-building.ts +0 -221
  105. package/src/router/route-compiler.ts +0 -691
  106. package/src/router/route-matching.ts +0 -368
  107. package/src/router/route-trie.ts +0 -450
  108. package/src/router/router.ts +0 -1616
  109. package/src/router/server.ts +0 -684
  110. package/src/router/validation-integration.ts +0 -449
  111. package/src/router/view-rendering.ts +0 -233
  112. package/src/router/websocket.ts +0 -100
  113. package/src/routing/route-caching.ts +0 -402
  114. package/src/routing/route-throttling.ts +0 -469
  115. package/src/routing/subdomain-routing.ts +0 -492
  116. package/src/session/database-store.ts +0 -109
  117. package/src/session/file-store.ts +0 -148
  118. package/src/session/index.ts +0 -244
  119. package/src/session/memory-store.ts +0 -88
  120. package/src/session/redis-store.ts +0 -93
  121. package/src/streaming/index.ts +0 -17
  122. package/src/streaming/sse-handler.ts +0 -482
  123. package/src/streaming/stream-handler.ts +0 -552
  124. package/src/testing/auth-testing.ts +0 -448
  125. package/src/testing/file-upload-testing.ts +0 -543
  126. package/src/testing/index.ts +0 -10
  127. package/src/testing/middleware-testing.ts +0 -322
  128. package/src/testing/model-binding-testing.ts +0 -645
  129. package/src/testing/performance-testing.ts +0 -738
  130. package/src/testing/test-client.ts +0 -310
  131. package/src/testing/test-request.ts +0 -315
  132. package/src/testing/test-response.ts +0 -332
  133. package/src/testing/types.ts +0 -224
  134. package/src/testing/websocket-testing.ts +0 -590
  135. package/src/types/controller-types.ts +0 -385
  136. package/src/types/core.ts +0 -683
  137. package/src/types/middleware-types.ts +0 -422
  138. package/src/types/request-response-augmentation.ts +0 -489
  139. package/src/types/route-inference.ts +0 -372
  140. package/src/types.ts +0 -2123
  141. package/src/url.ts +0 -131
  142. package/src/utils/index.ts +0 -1
  143. package/src/utils/query-preservation.ts +0 -201
  144. package/src/utils.ts +0 -395
  145. package/src/validation/validator.ts +0 -688
  146. package/src/websocket/clustering.ts +0 -769
@@ -1,569 +0,0 @@
1
- /**
2
- * Advanced Error Handling - Main Error Handler Middleware
3
- *
4
- * Unified error handling middleware that integrates all error handling components
5
- */
6
-
7
- import type { CircuitBreakerConfig, DegradationConfig, EnhancedRequest, ErrorContext, ErrorReportingConfig } from '../types'
8
- import { CircuitBreakerRegistry } from './circuit-breaker'
9
- import { ErrorReportingManager } from './error-reporting'
10
- import { ErrorFactory, RouterException } from './exceptions'
11
- import { GracefulDegradationManager } from './graceful-degradation'
12
-
13
- export interface AdvancedErrorHandlerConfig {
14
- errorReporting?: ErrorReportingConfig[]
15
- gracefulDegradation?: DegradationConfig
16
- circuitBreakers?: CircuitBreakerConfig[]
17
- globalErrorHandler?: (error: RouterException, req: EnhancedRequest) => Promise<Response>
18
- development?: boolean
19
- includeStackTrace?: boolean
20
- sanitizeErrors?: boolean
21
- logErrors?: boolean
22
- customErrorPages?: {
23
- [statusCode: number]: string | ((_error: RouterException, _req: EnhancedRequest) => Promise<Response>)
24
- }
25
- }
26
-
27
- /**
28
- * Advanced error handler middleware
29
- */
30
- export class AdvancedErrorHandler {
31
- private errorReporting?: ErrorReportingManager
32
- private gracefulDegradation?: GracefulDegradationManager
33
- private circuitBreakerRegistry?: CircuitBreakerRegistry
34
- private config: AdvancedErrorHandlerConfig
35
-
36
- constructor(config: AdvancedErrorHandlerConfig = {}) {
37
- this.config = {
38
- development: false,
39
- includeStackTrace: false,
40
- sanitizeErrors: true,
41
- logErrors: true,
42
- ...config,
43
- }
44
-
45
- this.initializeComponents()
46
- }
47
-
48
- private initializeComponents(): void {
49
- // Initialize error reporting
50
- if (this.config.errorReporting?.length) {
51
- this.errorReporting = new ErrorReportingManager(this.config.errorReporting)
52
- }
53
-
54
- // Initialize graceful degradation
55
- if (this.config.gracefulDegradation?.enabled) {
56
- this.gracefulDegradation = new GracefulDegradationManager(this.config.gracefulDegradation)
57
- }
58
-
59
- // Initialize circuit breakers
60
- if (this.config.circuitBreakers?.length) {
61
- this.circuitBreakerRegistry = new CircuitBreakerRegistry()
62
- for (const config of this.config.circuitBreakers) {
63
- this.circuitBreakerRegistry.register(config)
64
- }
65
- }
66
- }
67
-
68
- /**
69
- * Main error handling middleware
70
- */
71
- middleware() {
72
- return async (req: EnhancedRequest, next: () => Promise<Response>): Promise<Response> => {
73
- try {
74
- // Add error context to request
75
- const errorContext: ErrorContext = {
76
- requestId: req.requestId,
77
- userId: req.user?.id,
78
- traceId: req.traceId,
79
- spanId: req.spanId,
80
- route: req.params?.route || req.url,
81
- method: req.method,
82
- url: req.url,
83
- userAgent: (req as any).userAgent?.() || undefined,
84
- ip: (req as any).ip?.() || undefined,
85
- timestamp: new Date(),
86
- }
87
-
88
- req.context = { ...req.context, errorContext }
89
-
90
- // Execute request with circuit breaker protection if configured
91
- if (this.circuitBreakerRegistry && req.context?.serviceName) {
92
- const breaker = this.circuitBreakerRegistry.get(req.context.serviceName as string)
93
- if (breaker) {
94
- return await breaker.execute({
95
- execute: next,
96
- context: errorContext,
97
- })
98
- }
99
- }
100
-
101
- return await next()
102
- }
103
- catch (error) {
104
- return this.handleError(error, req)
105
- }
106
- }
107
- }
108
-
109
- /**
110
- * Handle errors with full advanced error handling pipeline
111
- */
112
- async handleError(error: unknown, req: EnhancedRequest): Promise<Response> {
113
- // Convert to RouterException if needed
114
- const routerError = this.normalizeError(error, req)
115
-
116
- // Add breadcrumb for error reporting
117
- if (this.errorReporting) {
118
- this.errorReporting.addBreadcrumb(
119
- `Error in ${req.method} ${req.url}`,
120
- 'error',
121
- {
122
- code: routerError.code,
123
- severity: routerError.severity,
124
- statusCode: routerError.statusCode,
125
- },
126
- )
127
- }
128
-
129
- // Log error if configured
130
- if (this.config.logErrors) {
131
- this.logError(routerError, req)
132
- }
133
-
134
- // Try graceful degradation if configured
135
- if (this.gracefulDegradation && req.context?.serviceName) {
136
- try {
137
- return await this.gracefulDegradation.handleFailure(
138
- req.context.serviceName as string,
139
- routerError,
140
- req,
141
- async () => {
142
- throw routerError // This will trigger fallback strategies
143
- },
144
- )
145
- }
146
- catch {
147
- // Graceful degradation failed, continue with normal error handling
148
- }
149
- }
150
-
151
- // Report error to external services
152
- if (this.errorReporting) {
153
- try {
154
- await this.errorReporting.report(routerError, routerError.context)
155
- }
156
- catch (reportingError) {
157
- console.error('Failed to report error:', reportingError)
158
- }
159
- }
160
-
161
- // Use custom global error handler if provided
162
- if (this.config.globalErrorHandler) {
163
- try {
164
- return await this.config.globalErrorHandler(routerError, req)
165
- }
166
- catch (handlerError) {
167
- console.error('Global error handler failed:', handlerError)
168
- }
169
- }
170
-
171
- // Use custom error page if configured
172
- const customPage = this.config.customErrorPages?.[routerError.statusCode]
173
- if (customPage) {
174
- try {
175
- if (typeof customPage === 'string') {
176
- return new Response(customPage, {
177
- status: routerError.statusCode,
178
- headers: { 'Content-Type': 'text/html' },
179
- })
180
- }
181
- else {
182
- return await customPage(routerError, req)
183
- }
184
- }
185
- catch (pageError) {
186
- console.error('Custom error page failed:', pageError)
187
- }
188
- }
189
-
190
- // Default error response
191
- return this.createErrorResponse(routerError, req)
192
- }
193
-
194
- /**
195
- * Convert any error to RouterException
196
- */
197
- private normalizeError(error: unknown, req: EnhancedRequest): RouterException {
198
- const errorContext: ErrorContext = {
199
- requestId: req.requestId,
200
- userId: req.user?.id,
201
- traceId: req.traceId,
202
- spanId: req.spanId,
203
- route: req.params?.route || req.url,
204
- method: req.method,
205
- url: req.url,
206
- userAgent: (req as any).userAgent?.() || undefined,
207
- ip: (req as any).ip?.() || undefined,
208
- timestamp: new Date(),
209
- metadata: req.context,
210
- }
211
-
212
- // Already a RouterException
213
- if (error instanceof RouterException) {
214
- return error
215
- }
216
-
217
- // Standard Error
218
- if (error instanceof Error) {
219
- // Check for specific error types
220
- if (error.name === 'ValidationError') {
221
- return ErrorFactory.validation(error.message, {}, errorContext)
222
- }
223
-
224
- if (error.name === 'UnauthorizedError' || error.message.includes('unauthorized')) {
225
- return ErrorFactory.authentication(error.message, errorContext)
226
- }
227
-
228
- if (error.name === 'ForbiddenError' || error.message.includes('forbidden')) {
229
- return ErrorFactory.authorization(error.message, [], errorContext)
230
- }
231
-
232
- if (error.name === 'NotFoundError' || error.message.includes('not found')) {
233
- return ErrorFactory.notFound(undefined, undefined, errorContext)
234
- }
235
-
236
- if (error.name === 'TimeoutError' || error.message.includes('timeout')) {
237
- return ErrorFactory.timeout(30000, error.message, errorContext)
238
- }
239
-
240
- // Generic internal server error
241
- return ErrorFactory.internalServer(error.message, error, errorContext)
242
- }
243
-
244
- // String error
245
- if (typeof error === 'string') {
246
- return ErrorFactory.internalServer(error, undefined, errorContext)
247
- }
248
-
249
- // Unknown error type
250
- return ErrorFactory.internalServer('An unknown error occurred', undefined, errorContext)
251
- }
252
-
253
- /**
254
- * Create standardized error response
255
- */
256
- private createErrorResponse(error: RouterException, _req: EnhancedRequest): Response {
257
- const isDevelopment = this.config.development
258
- const includeStackTrace = this.config.includeStackTrace || isDevelopment
259
- const sanitizeErrors = this.config.sanitizeErrors && !isDevelopment
260
-
261
- // Sanitize error message for production
262
- let message = error.message
263
- if (sanitizeErrors && error.statusCode >= 500) {
264
- message = 'An internal server error occurred'
265
- }
266
-
267
- const errorResponse: any = {
268
- error: {
269
- code: error.code,
270
- message,
271
- statusCode: error.statusCode,
272
- timestamp: error.timestamp.toISOString(),
273
- requestId: error.context.requestId,
274
- traceId: error.context.traceId,
275
- },
276
- }
277
-
278
- // Add additional fields in development
279
- if (isDevelopment) {
280
- errorResponse.error.category = error.category
281
- errorResponse.error.severity = error.severity
282
- errorResponse.error.retryable = error.retryable
283
- errorResponse.error.context = error.context
284
- }
285
-
286
- // Add stack trace if configured
287
- if (includeStackTrace) {
288
- errorResponse.error.stack = error.stack
289
- if (error.cause) {
290
- errorResponse.error.cause = {
291
- name: error.cause.name,
292
- message: error.cause.message,
293
- stack: error.cause.stack,
294
- }
295
- }
296
- }
297
-
298
- // Add validation fields for validation errors
299
- if ('fields' in error) {
300
- errorResponse.error.fields = (error as any).fields
301
- }
302
-
303
- // Add specific error type fields
304
- if ('allowedMethods' in error) {
305
- errorResponse.error.allowedMethods = (error as any).allowedMethods
306
- }
307
-
308
- if ('retryAfter' in error) {
309
- errorResponse.error.retryAfter = (error as any).retryAfter
310
- }
311
-
312
- const headers = new Headers({
313
- 'Content-Type': 'application/json',
314
- 'X-Error-Code': error.code,
315
- 'X-Request-ID': error.context.requestId || '',
316
- 'X-Trace-ID': error.context.traceId || '',
317
- })
318
-
319
- // Add specific headers for certain error types
320
- if ('allowedMethods' in error) {
321
- headers.set('Allow', (error as any).allowedMethods.join(', '))
322
- }
323
-
324
- if ('retryAfter' in error) {
325
- headers.set('Retry-After', (error as any).retryAfter.toString())
326
- }
327
-
328
- if ('limit' in error) {
329
- headers.set('X-RateLimit-Limit', (error as any).limit.toString())
330
- headers.set('X-RateLimit-Remaining', (error as any).remaining.toString())
331
- }
332
-
333
- return new Response(JSON.stringify(errorResponse), {
334
- status: error.statusCode,
335
- headers,
336
- })
337
- }
338
-
339
- /**
340
- * Log error with appropriate level
341
- */
342
- private logError(error: RouterException, req: EnhancedRequest): void {
343
- const logData = {
344
- error: error.toJSON(),
345
- request: {
346
- method: req.method,
347
- url: req.url,
348
- headers: Object.fromEntries(req.headers.entries()),
349
- userAgent: (req as any).userAgent?.() || undefined,
350
- ip: (req as any).ip?.() || undefined,
351
- requestId: req.requestId,
352
- traceId: req.traceId,
353
- },
354
- }
355
-
356
- switch (error.severity) {
357
- case 'critical':
358
- console.error('[CRITICAL ERROR]', logData)
359
- break
360
- case 'high':
361
- console.error('[ERROR]', logData)
362
- break
363
- case 'medium':
364
- console.warn('[WARNING]', logData)
365
- break
366
- case 'low':
367
- console.warn('[INFO]', logData)
368
- break
369
- default:
370
- console.error('[ERROR]', logData)
371
- }
372
- }
373
-
374
- /**
375
- * Get error handler statistics
376
- */
377
- getStats(): {
378
- errorReporting?: any
379
- gracefulDegradation?: any
380
- circuitBreakers?: any
381
- } {
382
- return {
383
- errorReporting: this.errorReporting
384
- ? {
385
- breadcrumbs: this.errorReporting.getBreadcrumbs().length,
386
- }
387
- : undefined,
388
- gracefulDegradation: this.gracefulDegradation
389
- ? this.gracefulDegradation.getSystemHealth()
390
- : undefined,
391
- circuitBreakers: this.circuitBreakerRegistry
392
- ? this.circuitBreakerRegistry.getAllMetrics()
393
- : undefined,
394
- }
395
- }
396
-
397
- /**
398
- * Cleanup resources
399
- */
400
- async cleanup(): Promise<void> {
401
- if (this.errorReporting) {
402
- await this.errorReporting.close()
403
- }
404
-
405
- if (this.gracefulDegradation) {
406
- this.gracefulDegradation.stop()
407
- }
408
- }
409
- }
410
-
411
- /**
412
- * Factory function to create advanced error handler middleware
413
- */
414
- export function createAdvancedErrorHandler(config: AdvancedErrorHandlerConfig = {}): {
415
- middleware: (req: EnhancedRequest, next: () => Promise<Response>) => Promise<Response>
416
- getStats: () => { errorReporting?: any, gracefulDegradation?: any, circuitBreakers?: any }
417
- cleanup: () => Promise<void>
418
- } {
419
- const handler = new AdvancedErrorHandler(config)
420
- return {
421
- middleware: handler.middleware(),
422
- getStats: (): { errorReporting?: any, gracefulDegradation?: any, circuitBreakers?: any } => handler.getStats(),
423
- cleanup: (): Promise<void> => handler.cleanup(),
424
- }
425
- }
426
-
427
- /**
428
- * Preset configurations for different environments
429
- */
430
- export const ErrorHandlerPresets = {
431
- development: (): AdvancedErrorHandlerConfig => ({
432
- development: true,
433
- includeStackTrace: true,
434
- sanitizeErrors: false,
435
- logErrors: true,
436
- errorReporting: [],
437
- }),
438
-
439
- production: (sentryDsn?: string, bugsnagApiKey?: string): AdvancedErrorHandlerConfig => ({
440
- development: false,
441
- includeStackTrace: false,
442
- sanitizeErrors: true,
443
- logErrors: true,
444
- errorReporting: [
445
- ...(sentryDsn
446
- ? [{
447
- enabled: true,
448
- service: 'sentry' as const,
449
- dsn: sentryDsn,
450
- environment: 'production',
451
- sampleRate: 1.0,
452
- breadcrumbs: { enabled: true, maxBreadcrumbs: 100 },
453
- performance: { enabled: true, tracesSampleRate: 0.1 },
454
- }]
455
- : []),
456
- ...(bugsnagApiKey
457
- ? [{
458
- enabled: true,
459
- service: 'bugsnag' as const,
460
- apiKey: bugsnagApiKey,
461
- environment: 'production',
462
- breadcrumbs: { enabled: true, maxBreadcrumbs: 25 },
463
- }]
464
- : []),
465
- ],
466
- }),
467
-
468
- staging: (sentryDsn?: string): AdvancedErrorHandlerConfig => ({
469
- development: false,
470
- includeStackTrace: true,
471
- sanitizeErrors: false,
472
- logErrors: true,
473
- errorReporting: sentryDsn
474
- ? [{
475
- enabled: true,
476
- service: 'sentry',
477
- dsn: sentryDsn,
478
- environment: 'staging',
479
- sampleRate: 1.0,
480
- breadcrumbs: { enabled: true, maxBreadcrumbs: 100 },
481
- }]
482
- : [],
483
- }),
484
-
485
- resilient: (config: {
486
- sentryDsn?: string
487
- bugsnagApiKey?: string
488
- services?: string[]
489
- } = {}): AdvancedErrorHandlerConfig => ({
490
- development: false,
491
- includeStackTrace: false,
492
- sanitizeErrors: true,
493
- logErrors: true,
494
- errorReporting: [
495
- ...(config.sentryDsn
496
- ? [{
497
- enabled: true,
498
- service: 'sentry' as const,
499
- dsn: config.sentryDsn,
500
- environment: 'production',
501
- sampleRate: 1.0,
502
- breadcrumbs: { enabled: true, maxBreadcrumbs: 100 },
503
- performance: { enabled: true, tracesSampleRate: 0.1 },
504
- }]
505
- : []),
506
- ...(config.bugsnagApiKey
507
- ? [{
508
- enabled: true,
509
- service: 'bugsnag' as const,
510
- apiKey: config.bugsnagApiKey,
511
- environment: 'production',
512
- breadcrumbs: { enabled: true, maxBreadcrumbs: 25 },
513
- }]
514
- : []),
515
- ],
516
- gracefulDegradation: {
517
- enabled: true,
518
- fallbackStrategies: Object.fromEntries(
519
- (config.services || ['database', 'cache', 'external-api']).map(service => [
520
- service,
521
- {
522
- type: 'cache' as const,
523
- priority: 1,
524
- timeout: 5000,
525
- retries: 2,
526
- backoff: { type: 'exponential' as const, delay: 1000, maxDelay: 5000 },
527
- cacheConfig: {
528
- key: `${service}:{url}:{method}`,
529
- ttl: 3600,
530
- staleWhileRevalidate: true,
531
- },
532
- },
533
- ]),
534
- ),
535
- healthChecks: Object.fromEntries(
536
- (config.services || []).map(service => [
537
- service,
538
- {
539
- enabled: true,
540
- endpoint: `/health/${service}`,
541
- interval: 30000,
542
- timeout: 5000,
543
- retries: 3,
544
- expectedStatus: [200],
545
- },
546
- ]),
547
- ),
548
- monitoring: {
549
- enabled: true,
550
- alertThresholds: {
551
- errorRate: 10,
552
- responseTime: 5000,
553
- availability: 95,
554
- },
555
- },
556
- },
557
- circuitBreakers: (config.services || ['database', 'cache', 'external-api']).map(service => ({
558
- name: service,
559
- failureThreshold: 5,
560
- recoveryTimeout: 60000,
561
- timeout: 30000,
562
- monitoringPeriod: 60000,
563
- minimumRequests: 10,
564
- errorThresholdPercentage: 50,
565
- halfOpenMaxCalls: 3,
566
- resetTimeout: 60000,
567
- })),
568
- }),
569
- }