create-fluxstack 1.1.0 → 1.4.1
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.
- package/app/server/backend-only.ts +5 -5
- package/app/server/index.ts +63 -54
- package/app/server/live/FluxStackConfig.ts +43 -39
- package/app/server/live/SystemMonitorIntegration.ts +2 -2
- package/app/server/live/register-components.ts +1 -1
- package/app/server/middleware/errorHandling.ts +6 -4
- package/app/server/routes/config.ts +145 -0
- package/app/server/routes/index.ts +5 -3
- package/config/app.config.ts +113 -0
- package/config/build.config.ts +24 -0
- package/config/database.config.ts +99 -0
- package/config/index.ts +68 -0
- package/config/logger.config.ts +27 -0
- package/config/runtime.config.ts +92 -0
- package/config/server.config.ts +46 -0
- package/config/services.config.ts +130 -0
- package/config/system.config.ts +105 -0
- package/core/build/index.ts +10 -4
- package/core/cli/generators/index.ts +5 -2
- package/core/cli/generators/plugin.ts +290 -0
- package/core/cli/index.ts +117 -15
- package/core/config/env.ts +37 -95
- package/core/config/runtime-config.ts +61 -58
- package/core/config/schema.ts +4 -0
- package/core/framework/server.ts +22 -10
- package/core/plugins/built-in/index.ts +7 -17
- package/core/plugins/built-in/swagger/index.ts +228 -228
- package/core/plugins/built-in/vite/index.ts +374 -358
- package/core/plugins/dependency-manager.ts +5 -5
- package/core/plugins/manager.ts +12 -12
- package/core/plugins/registry.ts +3 -3
- package/core/server/index.ts +0 -1
- package/core/server/live/ComponentRegistry.ts +34 -8
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/websocket-plugin.ts +434 -434
- package/core/server/middleware/README.md +488 -0
- package/core/server/middleware/elysia-helpers.ts +227 -0
- package/core/server/middleware/index.ts +25 -9
- package/core/server/plugins/static-files-plugin.ts +231 -231
- package/core/utils/config-schema.ts +484 -0
- package/core/utils/env.ts +306 -0
- package/core/utils/helpers.ts +4 -4
- package/core/utils/logger/colors.ts +114 -0
- package/core/utils/logger/config.ts +35 -0
- package/core/utils/logger/formatter.ts +82 -0
- package/core/utils/logger/group-logger.ts +101 -0
- package/core/utils/logger/index.ts +199 -250
- package/core/utils/logger/stack-trace.ts +92 -0
- package/core/utils/logger/startup-banner.ts +92 -0
- package/core/utils/logger/winston-logger.ts +152 -0
- package/core/utils/version.ts +5 -0
- package/create-fluxstack.ts +118 -8
- package/fluxstack.config.ts +2 -2
- package/package.json +117 -115
- package/core/config/env-dynamic.ts +0 -326
- package/core/plugins/built-in/logger/index.ts +0 -180
- package/core/server/plugins/logger.ts +0 -47
- package/core/utils/env-runtime-v2.ts +0 -232
- package/core/utils/env-runtime.ts +0 -259
- package/core/utils/logger/formatters.ts +0 -222
- package/core/utils/logger/middleware.ts +0 -253
- package/core/utils/logger/performance.ts +0 -384
- package/core/utils/logger/transports.ts +0 -365
- package/core/utils/logger.ts +0 -106
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Runtime Configuration System for FluxStack
|
|
3
|
-
* Uses
|
|
4
|
-
* Drop-in replacement for process.env based configuration
|
|
3
|
+
* Uses declarative configuration system
|
|
5
4
|
*/
|
|
6
5
|
|
|
7
|
-
import { env,
|
|
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
|
|
34
|
+
* Load from environment variables
|
|
39
35
|
*/
|
|
40
36
|
private loadFromDynamicEnv(): this {
|
|
41
|
-
|
|
42
|
-
|
|
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.
|
|
68
|
-
|
|
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',
|
|
144
|
-
.override('logging.format',
|
|
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',
|
|
157
|
-
.override('logging.format',
|
|
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',
|
|
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',
|
|
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
|
|
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:
|
|
218
|
-
|
|
223
|
+
database: createNamespace('DATABASE_'),
|
|
224
|
+
|
|
219
225
|
/**
|
|
220
226
|
* JWT environment loader
|
|
221
227
|
*/
|
|
222
|
-
jwt:
|
|
223
|
-
|
|
228
|
+
jwt: createNamespace('JWT_'),
|
|
229
|
+
|
|
224
230
|
/**
|
|
225
231
|
* SMTP environment loader
|
|
226
232
|
*/
|
|
227
|
-
smtp:
|
|
228
|
-
|
|
233
|
+
smtp: createNamespace('SMTP_'),
|
|
234
|
+
|
|
229
235
|
/**
|
|
230
236
|
* CORS environment loader
|
|
231
237
|
*/
|
|
232
|
-
cors:
|
|
233
|
-
|
|
238
|
+
cors: createNamespace('CORS_'),
|
|
239
|
+
|
|
234
240
|
/**
|
|
235
241
|
* FluxStack specific environment loader
|
|
236
242
|
*/
|
|
237
|
-
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.
|
|
249
|
-
|
|
250
|
-
if (url) {
|
|
251
|
-
|
|
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.
|
|
265
|
-
|
|
266
|
-
if (origins.length === 0) {
|
|
267
|
-
const environment = env.
|
|
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.
|
|
285
|
-
host: env.
|
|
286
|
-
apiPrefix: env.
|
|
287
|
+
port: env.PORT,
|
|
288
|
+
host: env.HOST,
|
|
289
|
+
apiPrefix: env.API_PREFIX,
|
|
287
290
|
cors: {
|
|
288
291
|
origins: this.getCorsOrigins(),
|
|
289
|
-
methods: env.
|
|
290
|
-
headers: env.
|
|
291
|
-
credentials: env.
|
|
292
|
-
maxAge: env.
|
|
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.
|
|
305
|
+
port: env.VITE_PORT,
|
|
303
306
|
proxy: {
|
|
304
|
-
target:
|
|
305
|
-
changeOrigin:
|
|
307
|
+
target: buildConfig.apiUrl,
|
|
308
|
+
changeOrigin: buildConfig.proxyChangeOrigin
|
|
306
309
|
},
|
|
307
310
|
build: {
|
|
308
|
-
outDir:
|
|
309
|
-
sourceMaps:
|
|
310
|
-
minify:
|
|
311
|
-
target:
|
|
311
|
+
outDir: buildConfig.clientBuildDir,
|
|
312
|
+
sourceMaps: buildConfig.clientSourceMaps,
|
|
313
|
+
minify: buildConfig.clientMinify,
|
|
314
|
+
target: buildConfig.clientTarget
|
|
312
315
|
}
|
|
313
316
|
}
|
|
314
317
|
}
|
package/core/config/schema.ts
CHANGED
|
@@ -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
|
package/core/framework/server.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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: [
|
|
38
|
+
core: [staticPlugin],
|
|
41
39
|
development: [vitePlugin],
|
|
42
40
|
documentation: [swaggerPlugin],
|
|
43
|
-
monitoring: [
|
|
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 = [
|
|
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 [
|
|
105
|
+
return [] // Minimal plugins for testing
|
|
116
106
|
default:
|
|
117
107
|
return basePlugins
|
|
118
108
|
}
|