create-fluxstack 1.8.1 → 1.8.3

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 (132) hide show
  1. package/.env.example +19 -0
  2. package/README.md +6 -3
  3. package/app/client/SIMPLIFICATION.md +140 -0
  4. package/app/client/frontend-only.ts +1 -1
  5. package/app/client/src/App.tsx +148 -283
  6. package/app/client/src/index.css +5 -20
  7. package/app/client/src/lib/eden-api.ts +53 -220
  8. package/app/client/src/main.tsx +2 -3
  9. package/app/server/controllers/users.controller.ts +57 -31
  10. package/app/server/index.ts +5 -2
  11. package/app/server/live/register-components.ts +18 -7
  12. package/app/server/routes/env-test.ts +53 -2
  13. package/app/server/routes/index.ts +1 -8
  14. package/app/server/routes/users.routes.ts +192 -91
  15. package/config/fluxstack.config.ts +2 -2
  16. package/config/plugins.config.ts +22 -1
  17. package/core/build/flux-plugins-generator.ts +5 -5
  18. package/core/build/live-components-generator.ts +15 -12
  19. package/core/cli/command-registry.ts +4 -14
  20. package/core/cli/commands/plugin-deps.ts +8 -8
  21. package/core/cli/generators/component.ts +3 -3
  22. package/core/cli/generators/controller.ts +4 -4
  23. package/core/cli/generators/index.ts +8 -8
  24. package/core/cli/generators/interactive.ts +4 -4
  25. package/core/cli/generators/plugin.ts +3 -3
  26. package/core/cli/generators/prompts.ts +1 -1
  27. package/core/cli/generators/route.ts +27 -11
  28. package/core/cli/generators/service.ts +5 -5
  29. package/core/cli/generators/template-engine.ts +1 -1
  30. package/core/cli/generators/types.ts +1 -1
  31. package/core/cli/index.ts +158 -193
  32. package/core/cli/plugin-discovery.ts +3 -3
  33. package/core/client/hooks/index.ts +2 -2
  34. package/core/client/hooks/state-validator.ts +1 -1
  35. package/core/client/hooks/useAuth.ts +1 -1
  36. package/core/client/hooks/useChunkedUpload.ts +1 -1
  37. package/core/client/hooks/useHybridLiveComponent.ts +1 -1
  38. package/core/client/hooks/useWebSocket.ts +1 -1
  39. package/core/config/env.ts +1 -1
  40. package/core/config/runtime-config.ts +5 -5
  41. package/core/config/schema.ts +9 -0
  42. package/core/framework/server.ts +30 -15
  43. package/core/framework/types.ts +2 -2
  44. package/core/live/ComponentRegistry.ts +1 -1
  45. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1 -1
  46. package/core/plugins/built-in/live-components/index.ts +1 -1
  47. package/core/plugins/built-in/monitoring/index.ts +65 -161
  48. package/core/plugins/built-in/static/index.ts +18 -47
  49. package/core/plugins/built-in/swagger/index.ts +301 -231
  50. package/core/plugins/built-in/vite/index.ts +74 -109
  51. package/core/plugins/config.ts +2 -2
  52. package/core/plugins/dependency-manager.ts +2 -2
  53. package/core/plugins/discovery.ts +1 -1
  54. package/core/plugins/executor.ts +2 -2
  55. package/core/plugins/manager.ts +19 -4
  56. package/core/plugins/module-resolver.ts +1 -1
  57. package/core/plugins/registry.ts +3 -3
  58. package/core/plugins/types.ts +147 -5
  59. package/core/server/framework.ts +2 -2
  60. package/core/server/live/ComponentRegistry.ts +9 -26
  61. package/core/server/live/FileUploadManager.ts +1 -1
  62. package/core/server/live/auto-generated-components.ts +26 -0
  63. package/core/server/live/websocket-plugin.ts +211 -19
  64. package/core/server/middleware/errorHandling.ts +1 -1
  65. package/core/server/middleware/index.ts +4 -4
  66. package/core/server/plugins/database.ts +1 -2
  67. package/core/server/plugins/static-files-plugin.ts +259 -231
  68. package/core/server/plugins/swagger.ts +1 -1
  69. package/core/server/services/BaseService.ts +1 -1
  70. package/core/server/services/ServiceContainer.ts +1 -1
  71. package/core/server/services/index.ts +4 -4
  72. package/core/server/standalone.ts +16 -1
  73. package/core/testing/index.ts +1 -1
  74. package/core/testing/setup.ts +1 -1
  75. package/core/utils/logger/startup-banner.ts +7 -33
  76. package/core/utils/version.ts +6 -6
  77. package/create-fluxstack.ts +68 -25
  78. package/package.json +2 -2
  79. package/plugins/crypto-auth/index.ts +52 -47
  80. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  81. package/plugins/crypto-auth/server/middlewares/helpers.ts +16 -1
  82. package/vitest.config.ts +11 -2
  83. package/app/client/src/App.css +0 -883
  84. package/app/client/src/components/ErrorBoundary.tsx +0 -107
  85. package/app/client/src/components/ErrorDisplay.css +0 -365
  86. package/app/client/src/components/ErrorDisplay.tsx +0 -258
  87. package/app/client/src/components/FluxStackConfig.tsx +0 -1321
  88. package/app/client/src/components/HybridLiveCounter.tsx +0 -140
  89. package/app/client/src/components/LiveClock.tsx +0 -286
  90. package/app/client/src/components/MainLayout.tsx +0 -388
  91. package/app/client/src/components/SidebarNavigation.tsx +0 -391
  92. package/app/client/src/components/StateDemo.tsx +0 -178
  93. package/app/client/src/components/SystemMonitor.tsx +0 -1044
  94. package/app/client/src/components/UserProfile.tsx +0 -809
  95. package/app/client/src/hooks/useAuth.ts +0 -39
  96. package/app/client/src/hooks/useNotifications.ts +0 -56
  97. package/app/client/src/lib/errors.ts +0 -340
  98. package/app/client/src/lib/hooks/useErrorHandler.ts +0 -258
  99. package/app/client/src/lib/index.ts +0 -45
  100. package/app/client/src/pages/ApiDocs.tsx +0 -182
  101. package/app/client/src/pages/CryptoAuthPage.tsx +0 -394
  102. package/app/client/src/pages/Demo.tsx +0 -174
  103. package/app/client/src/pages/HybridLive.tsx +0 -263
  104. package/app/client/src/pages/Overview.tsx +0 -155
  105. package/app/client/src/store/README.md +0 -43
  106. package/app/client/src/store/index.ts +0 -16
  107. package/app/client/src/store/slices/uiSlice.ts +0 -151
  108. package/app/client/src/store/slices/userSlice.ts +0 -161
  109. package/app/client/src/test/README.md +0 -257
  110. package/app/client/src/test/setup.ts +0 -70
  111. package/app/client/src/test/types.ts +0 -12
  112. package/app/server/live/CounterComponent.ts +0 -191
  113. package/app/server/live/FluxStackConfig.ts +0 -534
  114. package/app/server/live/SidebarNavigation.ts +0 -157
  115. package/app/server/live/SystemMonitor.ts +0 -595
  116. package/app/server/live/SystemMonitorIntegration.ts +0 -151
  117. package/app/server/live/UserProfileComponent.ts +0 -141
  118. package/app/server/middleware/auth.ts +0 -136
  119. package/app/server/middleware/errorHandling.ts +0 -252
  120. package/app/server/middleware/index.ts +0 -10
  121. package/app/server/middleware/rateLimit.ts +0 -193
  122. package/app/server/middleware/requestLogging.ts +0 -215
  123. package/app/server/middleware/validation.ts +0 -270
  124. package/app/server/routes/config.ts +0 -145
  125. package/app/server/routes/crypto-auth-demo.routes.ts +0 -167
  126. package/app/server/routes/example-with-crypto-auth.routes.ts +0 -235
  127. package/app/server/routes/exemplo-posts.routes.ts +0 -161
  128. package/app/server/routes/upload.ts +0 -92
  129. package/app/server/services/NotificationService.ts +0 -302
  130. package/app/server/services/UserService.ts +0 -222
  131. package/app/server/services/index.ts +0 -46
  132. package/app/server/types/index.ts +0 -1
@@ -1,14 +1,14 @@
1
1
  import { Elysia } from "elysia"
2
- import type { FluxStackConfig, FluxStackContext } from "../types"
3
- import type { FluxStack, PluginContext, PluginUtils } from "../plugins/types"
4
- import { PluginRegistry } from "../plugins/registry"
5
- import { PluginManager } from "../plugins/manager"
6
- import { getConfigSync, getEnvironmentInfo } from "../config"
7
- import { logger } from "../utils/logger"
8
- import { displayStartupBanner, type StartupInfo } from "../utils/logger/startup-banner"
9
- import { createErrorHandler } from "../utils/errors/handlers"
10
- import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
11
- import type { Plugin } from "../plugins"
2
+ import type { FluxStackConfig, FluxStackContext } from "@/core/types"
3
+ import type { FluxStack, PluginContext, PluginUtils } from "@/core/plugins/types"
4
+ import { PluginRegistry } from "@/core/plugins/registry"
5
+ import { PluginManager } from "@/core/plugins/manager"
6
+ import { getConfigSync, getEnvironmentInfo } from "@/core/config"
7
+ import { logger } from "@/core/utils/logger"
8
+ import { displayStartupBanner, type StartupInfo } from "@/core/utils/logger/startup-banner"
9
+ import { createErrorHandler } from "@/core/utils/errors/handlers"
10
+ import { createTimer, formatBytes, isProduction, isDevelopment } from "@/core/utils/helpers"
11
+ import type { Plugin } from "@/core/plugins"
12
12
 
13
13
  export class FluxStackFramework {
14
14
  private app: Elysia
@@ -19,6 +19,21 @@ export class FluxStackFramework {
19
19
  private isStarted: boolean = false
20
20
  private requestTimings: Map<string, number> = new Map()
21
21
 
22
+ /**
23
+ * Helper to safely parse request.url which might be relative or absolute
24
+ */
25
+ private parseRequestURL(request: Request): URL {
26
+ try {
27
+ // Try parsing as absolute URL first
28
+ return new URL(request.url)
29
+ } catch {
30
+ // If relative, use host from headers or default to localhost
31
+ const host = request.headers.get('host') || 'localhost'
32
+ const protocol = request.headers.get('x-forwarded-proto') || 'http'
33
+ return new URL(request.url, `${protocol}://${host}`)
34
+ }
35
+ }
36
+
22
37
  constructor(config?: Partial<FluxStackConfig>) {
23
38
  // Load the full configuration
24
39
  const fullConfig = config ? { ...getConfigSync(), ...config } : getConfigSync()
@@ -160,7 +175,7 @@ export class FluxStackFramework {
160
175
  private setupHeadHandler() {
161
176
  // Global HEAD handler to prevent Elysia's automatic HEAD conversion bug
162
177
  this.app.head("*", ({ request, set }) => {
163
- const url = new URL(request.url)
178
+ const url = this.parseRequestURL(request)
164
179
 
165
180
  // Handle API routes
166
181
  if (url.pathname.startsWith(this.context.config.server.apiPrefix)) {
@@ -234,7 +249,7 @@ export class FluxStackFramework {
234
249
  // Setup onRequest hook and onBeforeRoute hook
235
250
  this.app.onRequest(async ({ request, set }) => {
236
251
  const startTime = Date.now()
237
- const url = new URL(request.url)
252
+ const url = this.parseRequestURL(request)
238
253
 
239
254
  // Store start time for duration calculation (using request URL as key)
240
255
  const requestKey = `${request.method}-${url.pathname}-${startTime}`
@@ -275,7 +290,7 @@ export class FluxStackFramework {
275
290
 
276
291
  // Setup onResponse hook
277
292
  this.app.onAfterHandle(async ({ request, response, set }) => {
278
- const url = new URL(request.url)
293
+ const url = this.parseRequestURL(request)
279
294
 
280
295
  // Retrieve start time using the timing key
281
296
  const requestKey = set.headers['x-request-timing-key']
@@ -329,7 +344,7 @@ export class FluxStackFramework {
329
344
 
330
345
  this.app.onError(async ({ error, request, path, set }) => {
331
346
  const startTime = Date.now()
332
- const url = new URL(request.url)
347
+ const url = this.parseRequestURL(request)
333
348
 
334
349
  const errorContext = {
335
350
  request,
@@ -448,7 +463,7 @@ export class FluxStackFramework {
448
463
 
449
464
  private async handleViteProxy(errorContext: any): Promise<Response> {
450
465
  const vitePort = this.context.config.client?.port || 5173
451
- const url = new URL(errorContext.request.url)
466
+ const url = this.parseRequestURL(errorContext.request)
452
467
 
453
468
  try {
454
469
  const viteUrl = `http://localhost:${vitePort}${url.pathname}${url.search}`
@@ -3,8 +3,8 @@
3
3
  * Defines the main interfaces and types for the FluxStack framework
4
4
  */
5
5
 
6
- import type { FluxStackConfig } from "../types"
7
- import type { Logger } from "../utils/logger/index"
6
+ import type { FluxStackConfig } from "@/core/types"
7
+ import type { Logger } from "@/core/utils/logger/index"
8
8
 
9
9
  export interface FluxStackFrameworkOptions {
10
10
  config?: Partial<FluxStackConfig>
@@ -6,7 +6,7 @@ import type {
6
6
  BroadcastMessage,
7
7
  ComponentDefinition,
8
8
  WebSocketData
9
- } from '../types/types'
9
+ } from '@/core/types/types'
10
10
 
11
11
  export class ComponentRegistry {
12
12
  private components = new Map<string, LiveComponent>()
@@ -1,4 +1,4 @@
1
- import type { CliCommand } from "../../../types";
1
+ import type { CliCommand } from "@/core/plugins/types";
2
2
  import { promises as fs } from "fs";
3
3
  import path from "path";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { FluxStack, PluginContext } from '../../types'
1
+ import type { FluxStack, PluginContext } from '@/core/plugins/types'
2
2
  import { createLiveComponentCommand } from './commands/create-live-component'
3
3
 
4
4
  type Plugin = FluxStack.Plugin
@@ -3,8 +3,10 @@
3
3
  * Provides performance monitoring, metrics collection, and system monitoring
4
4
  */
5
5
 
6
- import type { FluxStack, PluginContext, RequestContext, ResponseContext, ErrorContext } from "../../types"
7
- import { MetricsCollector } from "../../../utils/monitoring"
6
+ import type { FluxStack, PluginContext, RequestContext, ResponseContext, ErrorContext } from "@/core/plugins/types"
7
+ import { MetricsCollector } from "@/core/utils/monitoring"
8
+ import { appConfig } from '@/config/app.config'
9
+ import { monitoringConfig } from '@/config/monitoring.config'
8
10
  import * as os from 'os'
9
11
  import * as fs from 'fs'
10
12
  import * as path from 'path'
@@ -63,6 +65,36 @@ export interface AlertThreshold {
63
65
 
64
66
  type Plugin = FluxStack.Plugin
65
67
 
68
+ // Default configuration values (uses monitoringConfig from /config)
69
+ const DEFAULTS = {
70
+ enabled: monitoringConfig.monitoring.enabled,
71
+ httpMetrics: monitoringConfig.metrics.httpMetrics,
72
+ systemMetrics: monitoringConfig.metrics.systemMetrics,
73
+ customMetrics: monitoringConfig.metrics.customMetrics,
74
+ collectInterval: monitoringConfig.metrics.collectInterval,
75
+ retentionPeriod: monitoringConfig.metrics.retentionPeriod,
76
+ exporters: [
77
+ {
78
+ type: "console" as "console" | "prometheus" | "json" | "file",
79
+ interval: 30000,
80
+ enabled: monitoringConfig.metrics.exportToConsole
81
+ },
82
+ {
83
+ type: "prometheus" as "console" | "prometheus" | "json" | "file",
84
+ endpoint: "/metrics",
85
+ enabled: true,
86
+ format: "text" as const
87
+ }
88
+ ] as MetricsExporter[],
89
+ thresholds: {
90
+ responseTime: 1000, // ms
91
+ errorRate: 0.05, // 5%
92
+ memoryUsage: 0.8, // 80%
93
+ cpuUsage: 0.8 // 80%
94
+ },
95
+ alerts: [] as AlertThreshold[]
96
+ }
97
+
66
98
  export const monitoringPlugin: Plugin = {
67
99
  name: "monitoring",
68
100
  version: "1.0.0",
@@ -71,137 +103,20 @@ export const monitoringPlugin: Plugin = {
71
103
  priority: 900, // Should run early to capture all metrics
72
104
  category: "monitoring",
73
105
  tags: ["monitoring", "metrics", "performance", "observability"],
74
- dependencies: [], // No dependencies
75
-
76
- configSchema: {
77
- type: "object",
78
- properties: {
79
- enabled: {
80
- type: "boolean",
81
- description: "Enable monitoring plugin"
82
- },
83
- httpMetrics: {
84
- type: "boolean",
85
- description: "Collect HTTP request/response metrics"
86
- },
87
- systemMetrics: {
88
- type: "boolean",
89
- description: "Collect system metrics (memory, CPU, etc.)"
90
- },
91
- customMetrics: {
92
- type: "boolean",
93
- description: "Enable custom metrics collection"
94
- },
95
- collectInterval: {
96
- type: "number",
97
- minimum: 1000,
98
- description: "Interval for collecting system metrics (ms)"
99
- },
100
- retentionPeriod: {
101
- type: "number",
102
- minimum: 60000,
103
- description: "How long to retain metrics in memory (ms)"
104
- },
105
- exporters: {
106
- type: "array",
107
- items: {
108
- type: "object",
109
- properties: {
110
- type: {
111
- type: "string",
112
- enum: ["prometheus", "json", "console", "file"]
113
- },
114
- endpoint: { type: "string" },
115
- interval: { type: "number" },
116
- enabled: { type: "boolean" },
117
- format: {
118
- type: "string",
119
- enum: ["text", "json"]
120
- },
121
- filePath: { type: "string" }
122
- },
123
- required: ["type"]
124
- },
125
- description: "Metrics exporters configuration"
126
- },
127
- thresholds: {
128
- type: "object",
129
- properties: {
130
- responseTime: { type: "number" },
131
- errorRate: { type: "number" },
132
- memoryUsage: { type: "number" },
133
- cpuUsage: { type: "number" }
134
- },
135
- description: "Alert thresholds"
136
- },
137
- alerts: {
138
- type: "array",
139
- items: {
140
- type: "object",
141
- properties: {
142
- metric: { type: "string" },
143
- operator: {
144
- type: "string",
145
- enum: [">", "<", ">=", "<=", "==", "!="]
146
- },
147
- value: { type: "number" },
148
- severity: {
149
- type: "string",
150
- enum: ["info", "warning", "error", "critical"]
151
- },
152
- message: { type: "string" }
153
- },
154
- required: ["metric", "operator", "value", "severity"]
155
- },
156
- description: "Custom alert configurations"
157
- }
158
- },
159
- additionalProperties: false
160
- },
161
-
162
- defaultConfig: {
163
- enabled: true,
164
- httpMetrics: true,
165
- systemMetrics: true,
166
- customMetrics: true,
167
- collectInterval: 5000,
168
- retentionPeriod: 300000, // 5 minutes
169
- exporters: [
170
- {
171
- type: "console",
172
- interval: 30000,
173
- enabled: false
174
- },
175
- {
176
- type: "prometheus",
177
- endpoint: "/metrics",
178
- enabled: true,
179
- format: "text"
180
- }
181
- ],
182
- thresholds: {
183
- responseTime: 1000, // ms
184
- errorRate: 0.05, // 5%
185
- memoryUsage: 0.8, // 80%
186
- cpuUsage: 0.8 // 80%
187
- },
188
- alerts: []
189
- },
106
+ dependencies: [],
190
107
 
191
108
  setup: async (context: PluginContext) => {
192
- const config = getPluginConfig(context)
193
-
194
- if (!config.enabled) {
109
+ if (!DEFAULTS.enabled) {
195
110
  context.logger.info('Monitoring plugin disabled by configuration')
196
111
  return
197
112
  }
198
113
 
199
114
  context.logger.info('Initializing monitoring plugin', {
200
- httpMetrics: config.httpMetrics,
201
- systemMetrics: config.systemMetrics,
202
- customMetrics: config.customMetrics,
203
- exporters: config.exporters.length,
204
- alerts: config.alerts.length
115
+ httpMetrics: DEFAULTS.httpMetrics,
116
+ systemMetrics: DEFAULTS.systemMetrics,
117
+ customMetrics: DEFAULTS.customMetrics,
118
+ exporters: DEFAULTS.exporters.length,
119
+ alerts: DEFAULTS.alerts.length
205
120
  })
206
121
 
207
122
  // Initialize enhanced metrics registry
@@ -219,36 +134,34 @@ export const monitoringPlugin: Plugin = {
219
134
  ;(context as any).metricsCollector = metricsCollector
220
135
 
221
136
  // Initialize HTTP metrics
222
- if (config.httpMetrics) {
137
+ if (DEFAULTS.httpMetrics) {
223
138
  initializeHttpMetrics(metricsRegistry, metricsCollector)
224
139
  }
225
140
 
226
141
  // Start system metrics collection
227
- if (config.systemMetrics) {
228
- startSystemMetricsCollection(context, config, metricsCollector)
142
+ if (DEFAULTS.systemMetrics) {
143
+ startSystemMetricsCollection(context, metricsCollector)
229
144
  }
230
145
 
231
146
  // Setup metrics endpoint for Prometheus
232
- setupMetricsEndpoint(context, config, metricsRegistry, metricsCollector)
147
+ setupMetricsEndpoint(context, metricsRegistry, metricsCollector)
233
148
 
234
149
  // Start metrics exporters
235
- startMetricsExporters(context, config, metricsRegistry, metricsCollector)
150
+ startMetricsExporters(context, metricsRegistry, metricsCollector)
236
151
 
237
152
  // Setup metrics cleanup
238
- setupMetricsCleanup(context, config, metricsRegistry)
153
+ setupMetricsCleanup(context, metricsRegistry)
239
154
 
240
155
  // Setup alert monitoring
241
- if (config.alerts.length > 0) {
242
- setupAlertMonitoring(context, config, metricsRegistry)
156
+ if (DEFAULTS.alerts.length > 0) {
157
+ setupAlertMonitoring(context, metricsRegistry)
243
158
  }
244
159
 
245
160
  context.logger.info('Monitoring plugin initialized successfully')
246
161
  },
247
162
 
248
163
  onServerStart: async (context: PluginContext) => {
249
- const config = getPluginConfig(context)
250
-
251
- if (config.enabled) {
164
+ if (DEFAULTS.enabled) {
252
165
  context.logger.info('Monitoring plugin: Server monitoring started', {
253
166
  pid: process.pid,
254
167
  nodeVersion: process.version,
@@ -258,17 +171,15 @@ export const monitoringPlugin: Plugin = {
258
171
  // Record server start metric
259
172
  const metricsRegistry = (context as any).metricsRegistry as MetricsRegistry
260
173
  if (metricsRegistry) {
261
- recordCounter(metricsRegistry, 'server_starts_total', 1, {
262
- version: context.config.app.version
174
+ recordCounter(metricsRegistry, 'server_starts_total', 1, {
175
+ version: appConfig.version
263
176
  })
264
177
  }
265
178
  }
266
179
  },
267
180
 
268
181
  onServerStop: async (context: PluginContext) => {
269
- const config = getPluginConfig(context)
270
-
271
- if (config.enabled) {
182
+ if (DEFAULTS.enabled) {
272
183
  context.logger.info('Monitoring plugin: Server monitoring stopped')
273
184
 
274
185
  // Record server stop metric
@@ -358,14 +269,13 @@ export const monitoringPlugin: Plugin = {
358
269
  )
359
270
 
360
271
  // Check thresholds and log warnings
361
- const config = getPluginConfig(responseContext)
362
- if (config.thresholds.responseTime && duration > config.thresholds.responseTime) {
272
+ if (DEFAULTS.thresholds.responseTime && duration > DEFAULTS.thresholds.responseTime) {
363
273
  const logger = (responseContext as any).logger || console
364
274
  logger.warn(`Slow request detected: ${responseContext.method} ${responseContext.path} took ${duration}ms`, {
365
275
  method: responseContext.method,
366
276
  path: responseContext.path,
367
277
  duration,
368
- threshold: config.thresholds.responseTime
278
+ threshold: DEFAULTS.thresholds.responseTime
369
279
  })
370
280
  }
371
281
  },
@@ -410,12 +320,6 @@ export const monitoringPlugin: Plugin = {
410
320
 
411
321
  // Helper functions
412
322
 
413
- function getPluginConfig(context: any) {
414
- // In a real implementation, this would get the config from the plugin context
415
- const pluginConfig = context.config?.plugins?.config?.monitoring || {}
416
- return { ...monitoringPlugin.defaultConfig, ...pluginConfig }
417
- }
418
-
419
323
  function getMetricsRegistry(context: any): MetricsRegistry | null {
420
324
  // In a real implementation, this would get the registry from the plugin context
421
325
  return (context as any).metricsRegistry || null
@@ -444,7 +348,7 @@ function initializeHttpMetrics(registry: MetricsRegistry, collector: MetricsColl
444
348
  collector.createHistogram('http_response_size_bytes', 'HTTP response size in bytes', [100, 1000, 10000, 100000, 1000000])
445
349
  }
446
350
 
447
- function startSystemMetricsCollection(context: PluginContext, config: any, collector: MetricsCollector) {
351
+ function startSystemMetricsCollection(context: PluginContext, collector: MetricsCollector) {
448
352
  const intervals: NodeJS.Timeout[] = []
449
353
 
450
354
  // Initialize system metrics in collector
@@ -518,16 +422,16 @@ function startSystemMetricsCollection(context: PluginContext, config: any, colle
518
422
 
519
423
  // Collect metrics immediately and then at intervals
520
424
  collectSystemMetrics()
521
- const interval = setInterval(collectSystemMetrics, config.collectInterval)
425
+ const interval = setInterval(collectSystemMetrics, DEFAULTS.collectInterval)
522
426
  intervals.push(interval)
523
427
 
524
428
  // Store intervals for cleanup
525
429
  ;(context as any).monitoringIntervals = intervals
526
430
  }
527
431
 
528
- function setupMetricsEndpoint(context: PluginContext, config: any, _registry: MetricsRegistry, collector: MetricsCollector) {
432
+ function setupMetricsEndpoint(context: PluginContext, _registry: MetricsRegistry, collector: MetricsCollector) {
529
433
  // Find Prometheus exporter configuration
530
- const prometheusExporter = config.exporters.find((e: any) => e.type === 'prometheus' && e.enabled)
434
+ const prometheusExporter = DEFAULTS.exporters.find((e: any) => e.type === 'prometheus' && e.enabled)
531
435
  if (!prometheusExporter) return
532
436
 
533
437
  const endpoint = prometheusExporter.endpoint || '/metrics'
@@ -547,10 +451,10 @@ function setupMetricsEndpoint(context: PluginContext, config: any, _registry: Me
547
451
  }
548
452
  }
549
453
 
550
- function startMetricsExporters(context: PluginContext, config: any, registry: MetricsRegistry, collector: MetricsCollector) {
454
+ function startMetricsExporters(context: PluginContext, registry: MetricsRegistry, collector: MetricsCollector) {
551
455
  const intervals: NodeJS.Timeout[] = (context as any).monitoringIntervals || []
552
456
 
553
- for (const exporterConfig of config.exporters) {
457
+ for (const exporterConfig of DEFAULTS.exporters) {
554
458
  if (!exporterConfig.enabled) continue
555
459
 
556
460
  const exportMetrics = () => {
@@ -588,11 +492,11 @@ function startMetricsExporters(context: PluginContext, config: any, registry: Me
588
492
  ;(context as any).monitoringIntervals = intervals
589
493
  }
590
494
 
591
- function setupAlertMonitoring(context: PluginContext, config: any, registry: MetricsRegistry) {
495
+ function setupAlertMonitoring(context: PluginContext, registry: MetricsRegistry) {
592
496
  const intervals: NodeJS.Timeout[] = (context as any).monitoringIntervals || []
593
497
 
594
498
  const checkAlerts = () => {
595
- for (const alert of config.alerts) {
499
+ for (const alert of DEFAULTS.alerts) {
596
500
  try {
597
501
  const metricValue = getMetricValue(registry, alert.metric)
598
502
  if (metricValue !== null && evaluateThreshold(metricValue, alert.operator, alert.value)) {
@@ -640,12 +544,12 @@ function setupAlertMonitoring(context: PluginContext, config: any, registry: Met
640
544
  ;(context as any).monitoringIntervals = intervals
641
545
  }
642
546
 
643
- function setupMetricsCleanup(context: PluginContext, config: any, registry: MetricsRegistry) {
547
+ function setupMetricsCleanup(context: PluginContext, registry: MetricsRegistry) {
644
548
  const intervals: NodeJS.Timeout[] = (context as any).monitoringIntervals || []
645
549
 
646
550
  const cleanup = () => {
647
551
  const now = Date.now()
648
- const cutoff = now - config.retentionPeriod
552
+ const cutoff = now - DEFAULTS.retentionPeriod
649
553
 
650
554
  // Clean up old metrics
651
555
  for (const [key, metric] of registry.counters.entries()) {
@@ -1,6 +1,13 @@
1
1
  import { join } from "path"
2
2
  import { statSync, existsSync } from "fs"
3
- import type { Plugin, PluginContext } from "../.."
3
+ import type { Plugin, PluginContext } from "@/core/plugins"
4
+
5
+ // Default configuration values
6
+ const DEFAULTS = {
7
+ enabled: true,
8
+ publicDir: "./dist/client",
9
+ indexFile: "index.html"
10
+ }
4
11
 
5
12
  export const staticPlugin: Plugin = {
6
13
  name: "static",
@@ -12,41 +19,14 @@ export const staticPlugin: Plugin = {
12
19
  tags: ["static", "files", "spa"],
13
20
  dependencies: [],
14
21
 
15
- configSchema: {
16
- type: "object",
17
- properties: {
18
- enabled: {
19
- type: "boolean",
20
- description: "Enable static file serving"
21
- },
22
- publicDir: {
23
- type: "string",
24
- description: "Directory for static files"
25
- },
26
- indexFile: {
27
- type: "string",
28
- description: "Index file for SPA routing"
29
- }
30
- },
31
- additionalProperties: false
32
- },
33
-
34
- defaultConfig: {
35
- enabled: true,
36
- publicDir: "./dist/client",
37
- indexFile: "index.html"
38
- },
39
-
40
22
  setup: async (context: PluginContext) => {
41
- const config = getPluginConfig(context)
42
-
43
- if (!config.enabled) {
23
+ if (!DEFAULTS.enabled) {
44
24
  context.logger.info('Static files plugin disabled')
45
25
  return
46
26
  }
47
27
 
48
28
  context.logger.info("Static files plugin activated", {
49
- publicDir: config.publicDir
29
+ publicDir: DEFAULTS.publicDir
50
30
  })
51
31
 
52
32
  // Static fallback handler (runs last)
@@ -61,9 +41,9 @@ export const staticPlugin: Plugin = {
61
41
  const isDev = context.utils.isDevelopment()
62
42
  let baseDir: string
63
43
 
64
- if (isDev && existsSync(config.publicDir)) {
44
+ if (isDev && existsSync(DEFAULTS.publicDir)) {
65
45
  // Development: use public directory
66
- baseDir = config.publicDir
46
+ baseDir = DEFAULTS.publicDir
67
47
  } else {
68
48
  // Production: try paths in order of preference
69
49
  if (existsSync('client')) {
@@ -74,13 +54,13 @@ export const staticPlugin: Plugin = {
74
54
  baseDir = 'dist/client'
75
55
  } else {
76
56
  // Fallback to configured path
77
- baseDir = config.publicDir
57
+ baseDir = DEFAULTS.publicDir
78
58
  }
79
59
  }
80
60
 
81
61
  // Root or empty path → index.html
82
62
  if (pathname === '/' || pathname === '') {
83
- pathname = `/${config.indexFile}`
63
+ pathname = `/${DEFAULTS.indexFile}`
84
64
  }
85
65
 
86
66
  const filePath = join(baseDir, pathname)
@@ -97,7 +77,7 @@ export const staticPlugin: Plugin = {
97
77
  }
98
78
 
99
79
  // SPA fallback: serve index.html for non-file routes
100
- const indexPath = join(baseDir, config.indexFile)
80
+ const indexPath = join(baseDir, DEFAULTS.indexFile)
101
81
  try {
102
82
  statSync(indexPath) // Ensure index exists
103
83
  return new Response(Bun.file(indexPath))
@@ -111,22 +91,13 @@ export const staticPlugin: Plugin = {
111
91
  },
112
92
 
113
93
  onServerStart: async (context: PluginContext) => {
114
- const config = getPluginConfig(context)
115
-
116
- if (config.enabled) {
94
+ if (DEFAULTS.enabled) {
117
95
  context.logger.info(`Static files plugin ready`, {
118
- publicDir: config.publicDir,
119
- indexFile: config.indexFile
96
+ publicDir: DEFAULTS.publicDir,
97
+ indexFile: DEFAULTS.indexFile
120
98
  })
121
99
  }
122
100
  }
123
101
  }
124
102
 
125
- // Helper function to get plugin config
126
- function getPluginConfig(context: PluginContext) {
127
- const pluginConfig = context.config.plugins.config?.static || {}
128
- return { ...staticPlugin.defaultConfig, ...pluginConfig }
129
- }
130
-
131
-
132
103
  export default staticPlugin