create-fluxstack 1.1.0 → 1.4.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 (62) hide show
  1. package/app/server/backend-only.ts +5 -5
  2. package/app/server/index.ts +63 -54
  3. package/app/server/live/FluxStackConfig.ts +43 -39
  4. package/app/server/live/SystemMonitorIntegration.ts +2 -2
  5. package/app/server/live/register-components.ts +1 -1
  6. package/app/server/middleware/errorHandling.ts +6 -4
  7. package/app/server/routes/config.ts +145 -0
  8. package/app/server/routes/index.ts +5 -3
  9. package/config/app.config.ts +113 -0
  10. package/config/build.config.ts +24 -0
  11. package/config/database.config.ts +99 -0
  12. package/config/index.ts +68 -0
  13. package/config/logger.config.ts +27 -0
  14. package/config/runtime.config.ts +92 -0
  15. package/config/server.config.ts +46 -0
  16. package/config/services.config.ts +130 -0
  17. package/config/system.config.ts +105 -0
  18. package/core/build/index.ts +10 -4
  19. package/core/cli/index.ts +29 -12
  20. package/core/config/env.ts +37 -95
  21. package/core/config/runtime-config.ts +61 -58
  22. package/core/config/schema.ts +4 -0
  23. package/core/framework/server.ts +22 -10
  24. package/core/plugins/built-in/index.ts +7 -17
  25. package/core/plugins/built-in/swagger/index.ts +228 -228
  26. package/core/plugins/built-in/vite/index.ts +374 -358
  27. package/core/plugins/dependency-manager.ts +5 -5
  28. package/core/plugins/manager.ts +12 -12
  29. package/core/plugins/registry.ts +3 -3
  30. package/core/server/index.ts +0 -1
  31. package/core/server/live/ComponentRegistry.ts +34 -8
  32. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  33. package/core/server/live/websocket-plugin.ts +434 -434
  34. package/core/server/middleware/README.md +488 -0
  35. package/core/server/middleware/elysia-helpers.ts +227 -0
  36. package/core/server/middleware/index.ts +25 -9
  37. package/core/server/plugins/static-files-plugin.ts +231 -231
  38. package/core/utils/config-schema.ts +484 -0
  39. package/core/utils/env.ts +306 -0
  40. package/core/utils/helpers.ts +4 -4
  41. package/core/utils/logger/colors.ts +114 -0
  42. package/core/utils/logger/config.ts +35 -0
  43. package/core/utils/logger/formatter.ts +82 -0
  44. package/core/utils/logger/group-logger.ts +101 -0
  45. package/core/utils/logger/index.ts +199 -250
  46. package/core/utils/logger/stack-trace.ts +92 -0
  47. package/core/utils/logger/startup-banner.ts +92 -0
  48. package/core/utils/logger/winston-logger.ts +152 -0
  49. package/core/utils/version.ts +5 -0
  50. package/create-fluxstack.ts +1 -0
  51. package/fluxstack.config.ts +2 -2
  52. package/package.json +117 -115
  53. package/core/config/env-dynamic.ts +0 -326
  54. package/core/plugins/built-in/logger/index.ts +0 -180
  55. package/core/server/plugins/logger.ts +0 -47
  56. package/core/utils/env-runtime-v2.ts +0 -232
  57. package/core/utils/env-runtime.ts +0 -259
  58. package/core/utils/logger/formatters.ts +0 -222
  59. package/core/utils/logger/middleware.ts +0 -253
  60. package/core/utils/logger/performance.ts +0 -384
  61. package/core/utils/logger/transports.ts +0 -365
  62. package/core/utils/logger.ts +0 -106
@@ -3,6 +3,7 @@
3
3
  * Handles environment variable processing and precedence
4
4
  */
5
5
 
6
+ import { env, helpers } from '../utils/env'
6
7
  import type { FluxStackConfig, LogLevel, BuildTarget, LogFormat } from './schema'
7
8
 
8
9
  export interface EnvironmentInfo {
@@ -24,8 +25,6 @@ export interface ConfigPrecedence {
24
25
  * Get current environment information
25
26
  */
26
27
  export function getEnvironmentInfo(): EnvironmentInfo {
27
- // Import here to avoid circular dependency
28
- const { env } = require('../utils/env-runtime-v2')
29
28
  const nodeEnv = env.NODE_ENV
30
29
 
31
30
  return {
@@ -99,117 +98,60 @@ export class EnvironmentProcessor {
99
98
  const config: any = {}
100
99
 
101
100
  // App configuration
102
- this.setConfigValue(config, 'app.name',
103
- process.env.FLUXSTACK_APP_NAME || process.env.APP_NAME, 'string')
104
- this.setConfigValue(config, 'app.version',
105
- process.env.FLUXSTACK_APP_VERSION || process.env.APP_VERSION, 'string')
106
- this.setConfigValue(config, 'app.description',
107
- process.env.FLUXSTACK_APP_DESCRIPTION || process.env.APP_DESCRIPTION, 'string')
101
+ this.setConfigValue(config, 'app.name', env.FLUXSTACK_APP_NAME, 'string')
102
+ this.setConfigValue(config, 'app.version', env.FLUXSTACK_APP_VERSION, 'string')
108
103
 
109
104
  // Server configuration
110
- this.setConfigValue(config, 'server.port',
111
- process.env.PORT || process.env.FLUXSTACK_PORT, 'number')
112
- this.setConfigValue(config, 'server.host',
113
- process.env.HOST || process.env.FLUXSTACK_HOST, 'string')
114
- this.setConfigValue(config, 'server.apiPrefix',
115
- process.env.FLUXSTACK_API_PREFIX || process.env.API_PREFIX, 'string')
105
+ this.setConfigValue(config, 'server.port', env.PORT?.toString(), 'number')
106
+ this.setConfigValue(config, 'server.host', env.HOST, 'string')
107
+ this.setConfigValue(config, 'server.apiPrefix', env.API_PREFIX, 'string')
116
108
 
117
109
  // CORS configuration
118
- this.setConfigValue(config, 'server.cors.origins',
119
- process.env.CORS_ORIGINS || process.env.FLUXSTACK_CORS_ORIGINS, 'array')
120
- this.setConfigValue(config, 'server.cors.methods',
121
- process.env.CORS_METHODS || process.env.FLUXSTACK_CORS_METHODS, 'array')
122
- this.setConfigValue(config, 'server.cors.headers',
123
- process.env.CORS_HEADERS || process.env.FLUXSTACK_CORS_HEADERS, 'array')
124
- this.setConfigValue(config, 'server.cors.credentials',
125
- process.env.CORS_CREDENTIALS || process.env.FLUXSTACK_CORS_CREDENTIALS, 'boolean')
126
- this.setConfigValue(config, 'server.cors.maxAge',
127
- process.env.CORS_MAX_AGE || process.env.FLUXSTACK_CORS_MAX_AGE, 'number')
110
+ const corsOriginsStr = env.has('CORS_ORIGINS') ? env.all().CORS_ORIGINS : undefined
111
+ const corsMethodsStr = env.has('CORS_METHODS') ? env.all().CORS_METHODS : undefined
112
+ const corsHeadersStr = env.has('CORS_HEADERS') ? env.all().CORS_HEADERS : undefined
113
+
114
+ this.setConfigValue(config, 'server.cors.origins', corsOriginsStr, 'array')
115
+ this.setConfigValue(config, 'server.cors.methods', corsMethodsStr, 'array')
116
+ this.setConfigValue(config, 'server.cors.headers', corsHeadersStr, 'array')
117
+ this.setConfigValue(config, 'server.cors.credentials', env.CORS_CREDENTIALS?.toString(), 'boolean')
118
+ this.setConfigValue(config, 'server.cors.maxAge', env.CORS_MAX_AGE?.toString(), 'number')
128
119
 
129
120
  // Client configuration
130
- this.setConfigValue(config, 'client.port',
131
- process.env.VITE_PORT || process.env.CLIENT_PORT || process.env.FLUXSTACK_CLIENT_PORT, 'number')
132
- this.setConfigValue(config, 'client.proxy.target',
133
- process.env.VITE_API_URL || process.env.API_URL || process.env.FLUXSTACK_PROXY_TARGET, 'string')
134
- this.setConfigValue(config, 'client.build.sourceMaps',
135
- process.env.FLUXSTACK_CLIENT_SOURCEMAPS, 'boolean')
136
- this.setConfigValue(config, 'client.build.minify',
137
- process.env.FLUXSTACK_CLIENT_MINIFY, 'boolean')
121
+ this.setConfigValue(config, 'client.port', env.VITE_PORT?.toString(), 'number')
138
122
 
139
123
  // Build configuration
140
- this.setConfigValue(config, 'build.target',
141
- process.env.BUILD_TARGET || process.env.FLUXSTACK_BUILD_TARGET, 'buildTarget')
142
- this.setConfigValue(config, 'build.outDir',
143
- process.env.BUILD_OUTDIR || process.env.FLUXSTACK_BUILD_OUTDIR, 'string')
144
- this.setConfigValue(config, 'build.sourceMaps',
145
- process.env.BUILD_SOURCEMAPS || process.env.FLUXSTACK_BUILD_SOURCEMAPS, 'boolean')
146
- this.setConfigValue(config, 'build.clean',
147
- process.env.BUILD_CLEAN || process.env.FLUXSTACK_BUILD_CLEAN, 'boolean')
148
-
149
- // Build optimization
150
- this.setConfigValue(config, 'build.optimization.minify',
151
- process.env.BUILD_MINIFY || process.env.FLUXSTACK_BUILD_MINIFY, 'boolean')
152
- this.setConfigValue(config, 'build.optimization.treeshake',
153
- process.env.BUILD_TREESHAKE || process.env.FLUXSTACK_BUILD_TREESHAKE, 'boolean')
154
- this.setConfigValue(config, 'build.optimization.compress',
155
- process.env.BUILD_COMPRESS || process.env.FLUXSTACK_BUILD_COMPRESS, 'boolean')
156
- this.setConfigValue(config, 'build.optimization.splitChunks',
157
- process.env.BUILD_SPLIT_CHUNKS || process.env.FLUXSTACK_BUILD_SPLIT_CHUNKS, 'boolean')
158
- this.setConfigValue(config, 'build.optimization.bundleAnalyzer',
159
- process.env.BUILD_ANALYZER || process.env.FLUXSTACK_BUILD_ANALYZER, 'boolean')
124
+ const buildMinify = env.has('BUILD_MINIFY') ? env.all().BUILD_MINIFY : undefined
125
+ this.setConfigValue(config, 'build.optimization.minify', buildMinify, 'boolean')
160
126
 
161
127
  // Logging configuration
162
- this.setConfigValue(config, 'logging.level',
163
- process.env.LOG_LEVEL || process.env.FLUXSTACK_LOG_LEVEL, 'logLevel')
164
- this.setConfigValue(config, 'logging.format',
165
- process.env.LOG_FORMAT || process.env.FLUXSTACK_LOG_FORMAT, 'logFormat')
128
+ this.setConfigValue(config, 'logging.level', env.LOG_LEVEL, 'logLevel')
129
+ this.setConfigValue(config, 'logging.format', env.LOG_FORMAT, 'logFormat')
166
130
 
167
131
  // Monitoring configuration
168
- this.setConfigValue(config, 'monitoring.enabled',
169
- process.env.MONITORING_ENABLED || process.env.FLUXSTACK_MONITORING_ENABLED, 'boolean')
170
- this.setConfigValue(config, 'monitoring.metrics.enabled',
171
- process.env.METRICS_ENABLED || process.env.FLUXSTACK_METRICS_ENABLED, 'boolean')
172
- this.setConfigValue(config, 'monitoring.metrics.collectInterval',
173
- process.env.METRICS_INTERVAL || process.env.FLUXSTACK_METRICS_INTERVAL, 'number')
174
- this.setConfigValue(config, 'monitoring.profiling.enabled',
175
- process.env.PROFILING_ENABLED || process.env.FLUXSTACK_PROFILING_ENABLED, 'boolean')
176
- this.setConfigValue(config, 'monitoring.profiling.sampleRate',
177
- process.env.PROFILING_SAMPLE_RATE || process.env.FLUXSTACK_PROFILING_SAMPLE_RATE, 'number')
132
+ this.setConfigValue(config, 'monitoring.enabled', env.ENABLE_MONITORING?.toString(), 'boolean')
133
+ this.setConfigValue(config, 'monitoring.metrics.enabled', env.ENABLE_METRICS?.toString(), 'boolean')
178
134
 
179
135
  // Database configuration
180
- this.setConfigValue(config, 'database.url', process.env.DATABASE_URL, 'string')
181
- this.setConfigValue(config, 'database.host', process.env.DATABASE_HOST, 'string')
182
- this.setConfigValue(config, 'database.port', process.env.DATABASE_PORT, 'number')
183
- this.setConfigValue(config, 'database.database', process.env.DATABASE_NAME, 'string')
184
- this.setConfigValue(config, 'database.user', process.env.DATABASE_USER, 'string')
185
- this.setConfigValue(config, 'database.password', process.env.DATABASE_PASSWORD, 'string')
186
- this.setConfigValue(config, 'database.ssl', process.env.DATABASE_SSL, 'boolean')
187
- this.setConfigValue(config, 'database.poolSize', process.env.DATABASE_POOL_SIZE, 'number')
136
+ this.setConfigValue(config, 'database.url', env.DATABASE_URL, 'string')
137
+ this.setConfigValue(config, 'database.host', env.DB_HOST, 'string')
138
+ this.setConfigValue(config, 'database.port', env.DB_PORT?.toString(), 'number')
139
+ this.setConfigValue(config, 'database.database', env.DB_NAME, 'string')
140
+ this.setConfigValue(config, 'database.user', env.DB_USER, 'string')
141
+ this.setConfigValue(config, 'database.password', env.DB_PASSWORD, 'string')
142
+ this.setConfigValue(config, 'database.ssl', env.DB_SSL?.toString(), 'boolean')
188
143
 
189
144
  // Auth configuration
190
- this.setConfigValue(config, 'auth.secret', process.env.JWT_SECRET, 'string')
191
- this.setConfigValue(config, 'auth.expiresIn', process.env.JWT_EXPIRES_IN, 'string')
192
- this.setConfigValue(config, 'auth.algorithm', process.env.JWT_ALGORITHM, 'string')
193
- this.setConfigValue(config, 'auth.issuer', process.env.JWT_ISSUER, 'string')
145
+ this.setConfigValue(config, 'auth.secret', env.JWT_SECRET, 'string')
146
+ this.setConfigValue(config, 'auth.expiresIn', env.JWT_EXPIRES_IN, 'string')
147
+ this.setConfigValue(config, 'auth.algorithm', env.JWT_ALGORITHM, 'string')
194
148
 
195
149
  // Email configuration
196
- this.setConfigValue(config, 'email.host', process.env.SMTP_HOST, 'string')
197
- this.setConfigValue(config, 'email.port', process.env.SMTP_PORT, 'number')
198
- this.setConfigValue(config, 'email.user', process.env.SMTP_USER, 'string')
199
- this.setConfigValue(config, 'email.password', process.env.SMTP_PASSWORD, 'string')
200
- this.setConfigValue(config, 'email.secure', process.env.SMTP_SECURE, 'boolean')
201
- this.setConfigValue(config, 'email.from', process.env.SMTP_FROM, 'string')
202
-
203
- // Storage configuration
204
- this.setConfigValue(config, 'storage.uploadPath', process.env.UPLOAD_PATH, 'string')
205
- this.setConfigValue(config, 'storage.maxFileSize', process.env.MAX_FILE_SIZE, 'number')
206
- this.setConfigValue(config, 'storage.provider', process.env.STORAGE_PROVIDER, 'string')
207
-
208
- // Plugin configuration
209
- this.setConfigValue(config, 'plugins.enabled',
210
- process.env.FLUXSTACK_PLUGINS_ENABLED, 'array')
211
- this.setConfigValue(config, 'plugins.disabled',
212
- process.env.FLUXSTACK_PLUGINS_DISABLED, 'array')
150
+ this.setConfigValue(config, 'email.host', env.SMTP_HOST, 'string')
151
+ this.setConfigValue(config, 'email.port', env.SMTP_PORT?.toString(), 'number')
152
+ this.setConfigValue(config, 'email.user', env.SMTP_USER, 'string')
153
+ this.setConfigValue(config, 'email.password', env.SMTP_PASSWORD, 'string')
154
+ this.setConfigValue(config, 'email.secure', env.SMTP_SECURE?.toString(), 'boolean')
213
155
 
214
156
  return this.cleanEmptyObjects(config)
215
157
  }
@@ -1,18 +1,14 @@
1
1
  /**
2
2
  * Runtime Configuration System for FluxStack
3
- * Uses dynamic environment loading to solve Bun build issues
4
- * Drop-in replacement for process.env based configuration
3
+ * Uses declarative configuration system
5
4
  */
6
5
 
7
- import { env, createEnvNamespace, envValidation } from '../utils/env-runtime'
8
- import {
9
- dynamicEnvironmentProcessor,
10
- createDynamicConfig,
11
- validateProductionEnv,
12
- getDynamicEnvironmentInfo
13
- } from './env-dynamic'
6
+ import { env, createNamespace } from '../utils/env'
14
7
  import type { FluxStackConfig } from './schema'
15
8
  import { defaultFluxStackConfig } from './schema'
9
+ import { loggerConfig } from '../../config/logger.config'
10
+ import { buildConfig } from '../../config/build.config'
11
+ import { appConfig } from '../../config/app.config'
16
12
 
17
13
  /**
18
14
  * Runtime Configuration Builder
@@ -35,11 +31,21 @@ export class RuntimeConfigBuilder {
35
31
  }
36
32
 
37
33
  /**
38
- * Load from dynamic environment variables
34
+ * Load from environment variables
39
35
  */
40
36
  private loadFromDynamicEnv(): this {
41
- const envConfig = createDynamicConfig()
42
- this.config = this.deepMerge(this.config, envConfig)
37
+ // Environment vars are loaded automatically by env loader
38
+ // Just merge common overrides here
39
+ const envOverrides: Partial<FluxStackConfig> = {}
40
+
41
+ if (env.has('PORT')) {
42
+ envOverrides.server = { ...this.config.server, port: env.PORT }
43
+ }
44
+ if (env.has('LOG_LEVEL')) {
45
+ envOverrides.logging = { ...this.config.logging, level: env.LOG_LEVEL }
46
+ }
47
+
48
+ this.config = this.deepMerge(this.config, envOverrides)
43
49
  return this
44
50
  }
45
51
 
@@ -64,8 +70,8 @@ export class RuntimeConfigBuilder {
64
70
  */
65
71
  build(): FluxStackConfig {
66
72
  // Validate production environment if needed
67
- if (env.get('NODE_ENV') === 'production') {
68
- validateProductionEnv()
73
+ if (env.NODE_ENV === 'production') {
74
+ env.require(['NODE_ENV'])
69
75
  }
70
76
 
71
77
  return this.config as FluxStackConfig
@@ -140,8 +146,8 @@ export const runtimeConfig = {
140
146
  */
141
147
  development(): FluxStackConfig {
142
148
  return new RuntimeConfigBuilder()
143
- .override('logging.level', env.get('LOG_LEVEL', 'debug'))
144
- .override('logging.format', env.get('LOG_FORMAT', 'pretty'))
149
+ .override('logging.level', loggerConfig.level)
150
+ .override('logging.format', 'pretty')
145
151
  .override('build.optimization.minify', false)
146
152
  .override('build.sourceMaps', true)
147
153
  .override('monitoring.enabled', false)
@@ -153,11 +159,11 @@ export const runtimeConfig = {
153
159
  */
154
160
  production(): FluxStackConfig {
155
161
  return new RuntimeConfigBuilder()
156
- .override('logging.level', env.get('LOG_LEVEL', 'warn'))
157
- .override('logging.format', env.get('LOG_FORMAT', 'json'))
162
+ .override('logging.level', loggerConfig.level)
163
+ .override('logging.format', 'json')
158
164
  .override('build.optimization.minify', true)
159
165
  .override('build.sourceMaps', false)
160
- .override('monitoring.enabled', env.bool('MONITORING_ENABLED', true))
166
+ .override('monitoring.enabled', buildConfig.monitoringEnabled)
161
167
  .build()
162
168
  },
163
169
 
@@ -166,7 +172,7 @@ export const runtimeConfig = {
166
172
  */
167
173
  test(): FluxStackConfig {
168
174
  return new RuntimeConfigBuilder()
169
- .override('logging.level', env.get('LOG_LEVEL', 'error'))
175
+ .override('logging.level', loggerConfig.level)
170
176
  .override('server.port', 0) // Random port for tests
171
177
  .override('client.port', 0)
172
178
  .override('monitoring.enabled', false)
@@ -177,7 +183,7 @@ export const runtimeConfig = {
177
183
  * Auto-detect environment and create appropriate config
178
184
  */
179
185
  auto(overrides?: Partial<FluxStackConfig>): FluxStackConfig {
180
- const environment = env.get('NODE_ENV', 'development') as 'development' | 'production' | 'test'
186
+ const environment = appConfig.env
181
187
 
182
188
  let config: FluxStackConfig
183
189
 
@@ -214,27 +220,27 @@ export const envLoaders = {
214
220
  /**
215
221
  * Database environment loader
216
222
  */
217
- database: createEnvNamespace('DATABASE_'),
218
-
223
+ database: createNamespace('DATABASE_'),
224
+
219
225
  /**
220
226
  * JWT environment loader
221
227
  */
222
- jwt: createEnvNamespace('JWT_'),
223
-
228
+ jwt: createNamespace('JWT_'),
229
+
224
230
  /**
225
231
  * SMTP environment loader
226
232
  */
227
- smtp: createEnvNamespace('SMTP_'),
228
-
233
+ smtp: createNamespace('SMTP_'),
234
+
229
235
  /**
230
236
  * CORS environment loader
231
237
  */
232
- cors: createEnvNamespace('CORS_'),
233
-
238
+ cors: createNamespace('CORS_'),
239
+
234
240
  /**
235
241
  * FluxStack specific environment loader
236
242
  */
237
- fluxstack: createEnvNamespace('FLUXSTACK_')
243
+ fluxstack: createNamespace('FLUXSTACK_')
238
244
  }
239
245
 
240
246
  /**
@@ -245,15 +251,12 @@ export const configHelpers = {
245
251
  * Get database URL with validation
246
252
  */
247
253
  getDatabaseUrl(): string | null {
248
- const url = env.get('DATABASE_URL') as string | undefined
249
-
250
- if (url) {
251
- envValidation.validate('DATABASE_URL',
252
- (value) => value.includes('://'),
253
- 'Must be a valid URL'
254
- )
254
+ const url = env.DATABASE_URL
255
+
256
+ if (url && !url.includes('://')) {
257
+ throw new Error('DATABASE_URL must be a valid URL')
255
258
  }
256
-
259
+
257
260
  return url || null
258
261
  },
259
262
 
@@ -261,18 +264,18 @@ export const configHelpers = {
261
264
  * Get CORS origins with proper defaults
262
265
  */
263
266
  getCorsOrigins(): string[] {
264
- const origins = env.array('CORS_ORIGINS')
265
-
266
- if (origins.length === 0) {
267
- const environment = env.get('NODE_ENV', 'development') as 'development' | 'production' | 'test'
268
-
267
+ const origins = env.CORS_ORIGINS
268
+
269
+ if (origins.length === 0 || (origins.length === 1 && origins[0] === '*')) {
270
+ const environment = env.NODE_ENV
271
+
269
272
  if (environment === 'development') {
270
273
  return ['http://localhost:3000', 'http://localhost:5173']
271
274
  } else if (environment === 'production') {
272
275
  return [] // Must be explicitly configured in production
273
276
  }
274
277
  }
275
-
278
+
276
279
  return origins
277
280
  },
278
281
 
@@ -281,15 +284,15 @@ export const configHelpers = {
281
284
  */
282
285
  getServerConfig() {
283
286
  return {
284
- port: env.num('PORT', 3000),
285
- host: env.get('HOST', 'localhost'),
286
- apiPrefix: env.get('API_PREFIX', '/api'),
287
+ port: env.PORT,
288
+ host: env.HOST,
289
+ apiPrefix: env.API_PREFIX,
287
290
  cors: {
288
291
  origins: this.getCorsOrigins(),
289
- methods: env.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
290
- headers: env.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
291
- credentials: env.bool('CORS_CREDENTIALS', false),
292
- maxAge: env.num('CORS_MAX_AGE', 86400)
292
+ methods: env.CORS_METHODS,
293
+ headers: env.CORS_HEADERS,
294
+ credentials: env.CORS_CREDENTIALS,
295
+ maxAge: env.CORS_MAX_AGE
293
296
  }
294
297
  }
295
298
  },
@@ -299,16 +302,16 @@ export const configHelpers = {
299
302
  */
300
303
  getClientConfig() {
301
304
  return {
302
- port: env.num('VITE_PORT', 5173),
305
+ port: env.VITE_PORT,
303
306
  proxy: {
304
- target: env.get('API_URL', 'http://localhost:3000'),
305
- changeOrigin: env.bool('PROXY_CHANGE_ORIGIN', true)
307
+ target: buildConfig.apiUrl,
308
+ changeOrigin: buildConfig.proxyChangeOrigin
306
309
  },
307
310
  build: {
308
- outDir: env.get('CLIENT_BUILD_DIR', 'dist/client'),
309
- sourceMaps: env.bool('CLIENT_SOURCEMAPS', env.get('NODE_ENV') === 'development'),
310
- minify: env.bool('CLIENT_MINIFY', env.get('NODE_ENV') === 'production'),
311
- target: env.get('CLIENT_TARGET', 'es2020')
311
+ outDir: buildConfig.clientBuildDir,
312
+ sourceMaps: buildConfig.clientSourceMaps,
313
+ minify: buildConfig.clientMinify,
314
+ target: buildConfig.clientTarget
312
315
  }
313
316
  }
314
317
  }
@@ -35,6 +35,7 @@ export interface ServerConfig {
35
35
  apiPrefix: string
36
36
  cors: CorsConfig
37
37
  middleware: MiddlewareConfig[]
38
+ showBanner?: boolean // Show startup banner (default: true)
38
39
  }
39
40
 
40
41
  export interface ProxyConfig {
@@ -45,6 +46,7 @@ export interface ProxyConfig {
45
46
 
46
47
  export interface ClientBuildConfig {
47
48
  sourceMaps: boolean
49
+ minify: boolean
48
50
  target: string
49
51
  outDir: string
50
52
  }
@@ -56,6 +58,7 @@ export interface ClientConfig {
56
58
  }
57
59
 
58
60
  export interface OptimizationConfig {
61
+ minify: boolean
59
62
  treeshake: boolean
60
63
  compress: boolean
61
64
  splitChunks: boolean
@@ -68,6 +71,7 @@ export interface BuildConfig {
68
71
  outDir: string
69
72
  optimization: OptimizationConfig
70
73
  sourceMaps: boolean
74
+ minify: boolean
71
75
  treeshake: boolean
72
76
  compress?: boolean
73
77
  removeUnusedCSS?: boolean
@@ -5,6 +5,7 @@ import { PluginRegistry } from "../plugins/registry"
5
5
  import { PluginManager } from "../plugins/manager"
6
6
  import { getConfigSync, getEnvironmentInfo } from "../config"
7
7
  import { logger } from "../utils/logger"
8
+ import { displayStartupBanner, type StartupInfo } from "../utils/logger/startup-banner"
8
9
  import { createErrorHandler } from "../utils/errors/handlers"
9
10
  import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
10
11
 
@@ -99,7 +100,7 @@ export class FluxStackFramework {
99
100
  this.setupHooks()
100
101
  this.setupErrorHandling()
101
102
 
102
- logger.framework('FluxStack framework initialized', {
103
+ logger.debug('FluxStack framework initialized', {
103
104
  environment: envInfo.name,
104
105
  port: fullConfig.server.port
105
106
  })
@@ -114,7 +115,7 @@ export class FluxStackFramework {
114
115
  try {
115
116
  await this.pluginManager.initialize()
116
117
  const stats = this.pluginManager.getRegistry().getStats()
117
- logger.framework('Automatic plugins loaded successfully', {
118
+ logger.debug('Automatic plugins loaded successfully', {
118
119
  pluginCount: stats.totalPlugins,
119
120
  enabledPlugins: stats.enabledPlugins,
120
121
  disabledPlugins: stats.disabledPlugins
@@ -420,7 +421,7 @@ export class FluxStackFramework {
420
421
  ;(this.pluginRegistry as any).loadOrder = loadOrder
421
422
  }
422
423
 
423
- logger.framework(`Plugin '${plugin.name}' registered`, {
424
+ logger.debug(`Plugin '${plugin.name}' registered`, {
424
425
  version: plugin.version,
425
426
  dependencies: plugin.dependencies
426
427
  })
@@ -478,7 +479,7 @@ export class FluxStackFramework {
478
479
  }
479
480
 
480
481
  this.isStarted = true
481
- logger.framework('All plugins loaded successfully', {
482
+ logger.debug('All plugins loaded successfully', {
482
483
  pluginCount: loadOrder.length
483
484
  })
484
485
 
@@ -535,15 +536,26 @@ export class FluxStackFramework {
535
536
  const apiPrefix = this.context.config.server.apiPrefix
536
537
 
537
538
  this.app.listen(port, () => {
538
- logger.framework(`Server started on port ${port}`, {
539
+ const showBanner = this.context.config.server.showBanner !== false // default: true
540
+ const vitePluginActive = this.pluginRegistry.has('vite')
541
+
542
+ // Prepare startup info for banner or callback
543
+ const startupInfo: StartupInfo = {
544
+ port,
539
545
  apiPrefix,
540
546
  environment: this.context.environment,
541
- pluginCount: this.pluginRegistry.getAll().length
542
- })
547
+ pluginCount: this.pluginRegistry.getAll().length,
548
+ vitePort: this.context.config.client?.port,
549
+ viteEmbedded: vitePluginActive, // Vite is embedded when plugin is active
550
+ swaggerPath: '/swagger' // TODO: Get from swagger plugin config
551
+ }
552
+
553
+ // Display banner if enabled
554
+ if (showBanner) {
555
+ displayStartupBanner(startupInfo)
556
+ }
543
557
 
544
- console.log(`🚀 API ready at http://localhost:${port}${apiPrefix}`)
545
- console.log(`📋 Health check: http://localhost:${port}${apiPrefix}/health`)
546
- console.log()
558
+ // Call user callback with startup info
547
559
  callback?.()
548
560
  })
549
561
 
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * Built-in Plugins for FluxStack
3
3
  * Core plugins that provide essential functionality
4
+ *
5
+ * Note: Logger is NOT a plugin - it's core infrastructure used by plugins
4
6
  */
5
7
 
6
8
  // Import all built-in plugins
7
- import { loggerPlugin } from './logger'
8
9
  import { swaggerPlugin } from './swagger'
9
10
  import { vitePlugin } from './vite'
10
11
  import { staticPlugin } from './static'
11
12
  import { monitoringPlugin } from './monitoring'
12
13
 
13
14
  // Export individual plugins
14
- export { loggerPlugin } from './logger'
15
15
  export { swaggerPlugin } from './swagger'
16
16
  export { vitePlugin } from './vite'
17
17
  export { staticPlugin } from './static'
@@ -19,7 +19,6 @@ export { monitoringPlugin } from './monitoring'
19
19
 
20
20
  // Export as a collection
21
21
  export const builtInPlugins = {
22
- logger: loggerPlugin,
23
22
  swagger: swaggerPlugin,
24
23
  vite: vitePlugin,
25
24
  static: staticPlugin,
@@ -28,7 +27,6 @@ export const builtInPlugins = {
28
27
 
29
28
  // Export as an array for easy registration
30
29
  export const builtInPluginsList = [
31
- loggerPlugin,
32
30
  swaggerPlugin,
33
31
  vitePlugin,
34
32
  staticPlugin,
@@ -37,22 +35,14 @@ export const builtInPluginsList = [
37
35
 
38
36
  // Plugin categories
39
37
  export const pluginCategories = {
40
- core: [loggerPlugin, staticPlugin],
38
+ core: [staticPlugin],
41
39
  development: [vitePlugin],
42
40
  documentation: [swaggerPlugin],
43
- monitoring: [loggerPlugin, monitoringPlugin]
41
+ monitoring: [monitoringPlugin]
44
42
  } as const
45
43
 
46
44
  // Default plugin configuration
47
45
  export const defaultPluginConfig = {
48
- logger: {
49
- logRequests: true,
50
- logResponses: true,
51
- logErrors: true,
52
- includeHeaders: false,
53
- includeBody: false,
54
- slowRequestThreshold: 1000
55
- },
56
46
  swagger: {
57
47
  enabled: true,
58
48
  path: '/swagger',
@@ -104,15 +94,15 @@ export const defaultPluginConfig = {
104
94
  * Get default plugins for a specific environment
105
95
  */
106
96
  export function getDefaultPlugins(environment: 'development' | 'production' | 'test' = 'development') {
107
- const basePlugins = [loggerPlugin, staticPlugin]
108
-
97
+ const basePlugins = [staticPlugin]
98
+
109
99
  switch (environment) {
110
100
  case 'development':
111
101
  return [...basePlugins, vitePlugin, swaggerPlugin, monitoringPlugin]
112
102
  case 'production':
113
103
  return [...basePlugins, monitoringPlugin]
114
104
  case 'test':
115
- return [loggerPlugin] // Minimal plugins for testing
105
+ return [] // Minimal plugins for testing
116
106
  default:
117
107
  return basePlugins
118
108
  }