create-fluxstack 1.7.5 โ†’ 1.8.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.
Files changed (39) hide show
  1. package/.dockerignore +82 -0
  2. package/Dockerfile +70 -0
  3. package/app/server/app.ts +20 -5
  4. package/app/server/backend-only.ts +15 -12
  5. package/app/server/index.ts +83 -96
  6. package/app/server/live/FluxStackConfig.ts +5 -5
  7. package/app/server/routes/env-test.ts +59 -0
  8. package/config/app.config.ts +2 -54
  9. package/config/client.config.ts +95 -0
  10. package/config/index.ts +57 -22
  11. package/config/monitoring.config.ts +114 -0
  12. package/config/plugins.config.ts +59 -0
  13. package/config/runtime.config.ts +0 -17
  14. package/config/server.config.ts +50 -30
  15. package/core/build/bundler.ts +17 -16
  16. package/core/build/flux-plugins-generator.ts +29 -18
  17. package/core/build/index.ts +32 -31
  18. package/core/build/live-components-generator.ts +29 -18
  19. package/core/build/optimizer.ts +37 -17
  20. package/core/cli/index.ts +6 -2
  21. package/core/config/env.ts +4 -0
  22. package/core/config/runtime-config.ts +10 -8
  23. package/core/config/schema.ts +24 -2
  24. package/core/framework/server.ts +1 -0
  25. package/core/index.ts +31 -23
  26. package/core/plugins/built-in/static/index.ts +73 -246
  27. package/core/plugins/built-in/vite/index.ts +377 -377
  28. package/core/plugins/registry.ts +22 -18
  29. package/core/server/backend-entry.ts +51 -0
  30. package/core/types/plugin.ts +6 -0
  31. package/core/utils/build-logger.ts +324 -0
  32. package/core/utils/config-schema.ts +2 -6
  33. package/core/utils/helpers.ts +14 -9
  34. package/core/utils/regenerate-files.ts +69 -0
  35. package/core/utils/version.ts +1 -1
  36. package/fluxstack.config.ts +138 -252
  37. package/package.json +2 -17
  38. package/vitest.config.ts +8 -26
  39. package/config/build.config.ts +0 -24
package/config/index.ts CHANGED
@@ -5,72 +5,107 @@
5
5
  *
6
6
  * @example
7
7
  * ```ts
8
- * import { appConfig, databaseConfig, servicesConfig } from '@/config'
8
+ * import { appConfig, serverConfig, databaseConfig } from '@/config'
9
9
  *
10
10
  * // All configs are type-safe and validated!
11
- * console.log(appConfig.name) // string
12
- * console.log(appConfig.port) // number
13
- * console.log(appConfig.debug) // boolean
11
+ * console.log(appConfig.name) // string
12
+ * console.log(serverConfig.server.port) // number
13
+ * console.log(clientConfig.vite.port) // number
14
14
  *
15
15
  * // Nested configs
16
- * console.log(servicesConfig.email.host) // string
17
- * console.log(servicesConfig.jwt.secret) // string
16
+ * console.log(servicesConfig.email.host) // string
17
+ * console.log(monitoringConfig.metrics.enabled) // boolean
18
18
  * ```
19
19
  */
20
20
 
21
+ // ============================================================================
22
+ // ๐Ÿ“ฆ CONFIG EXPORTS
23
+ // ============================================================================
24
+
21
25
  export { appConfig } from './app.config'
26
+ export { serverConfig } from './server.config'
27
+ export { clientConfig } from './client.config'
22
28
  export { databaseConfig } from './database.config'
23
29
  export { servicesConfig } from './services.config'
24
- export { serverConfig } from './server.config'
25
30
  export { loggerConfig } from './logger.config'
26
- export { buildConfig } from './build.config'
31
+ export { pluginsConfig } from './plugins.config'
32
+ export { monitoringConfig } from './monitoring.config'
27
33
  export { appRuntimeConfig } from './runtime.config'
28
34
  export { systemConfig, systemRuntimeInfo } from './system.config'
29
35
 
30
36
  // Plugin configs (re-exported for convenience)
31
37
  export { cryptoAuthConfig } from '../plugins/crypto-auth/config'
32
38
 
33
- // Re-export types
34
- export type { AppConfig } from './app.config'
39
+ // ============================================================================
40
+ // ๐Ÿ“ TYPE EXPORTS
41
+ // ============================================================================
42
+
43
+ // Core types
44
+ export type { AppConfig, Environment } from './app.config'
45
+ export type {
46
+ ServerConfig,
47
+ CorsConfig,
48
+ ServerFullConfig
49
+ } from './server.config'
50
+ export type {
51
+ ClientConfig,
52
+ ViteConfig,
53
+ ProxyConfig,
54
+ ClientBuildConfig
55
+ } from './client.config'
35
56
  export type { DatabaseConfig } from './database.config'
36
- export type { ServerConfig } from './server.config'
37
- export type { LoggerConfig } from './logger.config'
38
- export type { BuildConfig } from './build.config'
39
- export type { SystemConfig, SystemRuntimeInfo } from './system.config'
40
57
  export type {
41
58
  EmailConfig,
42
59
  JWTConfig,
43
60
  StorageConfig,
44
61
  RedisConfig
45
62
  } from './services.config'
63
+ export type { LoggerConfig } from './logger.config'
64
+ export type { PluginsConfig } from './plugins.config'
65
+ export type {
66
+ MonitoringConfig,
67
+ MetricsConfig,
68
+ ProfilingConfig,
69
+ MonitoringFullConfig
70
+ } from './monitoring.config'
71
+ export type { SystemConfig, SystemRuntimeInfo } from './system.config'
46
72
 
47
73
  // Plugin types
48
74
  export type { CryptoAuthConfig } from '../plugins/crypto-auth/config'
49
75
 
50
- /**
51
- * All configs in one object
52
- */
76
+ // ============================================================================
77
+ // ๐ŸŽฏ UNIFIED CONFIG OBJECT
78
+ // ============================================================================
79
+
53
80
  import { appConfig } from './app.config'
81
+ import { serverConfig } from './server.config'
82
+ import { clientConfig } from './client.config'
54
83
  import { databaseConfig } from './database.config'
55
84
  import { servicesConfig } from './services.config'
56
- import { serverConfig } from './server.config'
57
85
  import { loggerConfig } from './logger.config'
58
- import { buildConfig } from './build.config'
86
+ import { pluginsConfig } from './plugins.config'
87
+ import { monitoringConfig } from './monitoring.config'
59
88
  import { appRuntimeConfig } from './runtime.config'
60
89
  import { systemConfig, systemRuntimeInfo } from './system.config'
61
90
  import { cryptoAuthConfig } from '../plugins/crypto-auth/config'
62
91
 
92
+ /**
93
+ * All configs in one object
94
+ * Use this when you need access to multiple configs at once
95
+ */
63
96
  export const config = {
64
97
  app: appConfig,
98
+ server: serverConfig,
99
+ client: clientConfig,
65
100
  database: databaseConfig,
66
101
  services: servicesConfig,
67
- server: serverConfig,
68
102
  logger: loggerConfig,
69
- build: buildConfig,
103
+ plugins: pluginsConfig,
104
+ monitoring: monitoringConfig,
70
105
  runtime: appRuntimeConfig,
71
106
  system: systemConfig,
72
107
  systemRuntime: systemRuntimeInfo,
73
108
  cryptoAuth: cryptoAuthConfig
74
- }
109
+ } as const
75
110
 
76
111
  export default config
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Monitoring Configuration
3
+ * Declarative monitoring, metrics and profiling configuration
4
+ */
5
+
6
+ import { defineConfig, defineNestedConfig, config } from '@/core/utils/config-schema'
7
+ import { helpers } from '@/core/utils/env'
8
+
9
+ /**
10
+ * Metrics Configuration Schema
11
+ */
12
+ const metricsSchema = {
13
+ enabled: config.boolean('ENABLE_METRICS', false),
14
+
15
+ collectInterval: {
16
+ type: 'number' as const,
17
+ env: 'METRICS_INTERVAL',
18
+ default: 5000,
19
+ validate: (value: number) => {
20
+ if (value < 1000) {
21
+ return 'Metrics interval must be at least 1000ms'
22
+ }
23
+ return true
24
+ }
25
+ },
26
+
27
+ httpMetrics: config.boolean('HTTP_METRICS', true),
28
+
29
+ systemMetrics: config.boolean('SYSTEM_METRICS', true),
30
+
31
+ customMetrics: config.boolean('CUSTOM_METRICS', false),
32
+
33
+ // Metric exporters
34
+ exportToConsole: config.boolean('METRICS_EXPORT_CONSOLE', helpers.isDevelopment()),
35
+
36
+ exportToFile: config.boolean('METRICS_EXPORT_FILE', false),
37
+
38
+ exportToHttp: config.boolean('METRICS_EXPORT_HTTP', false),
39
+
40
+ exportHttpUrl: config.string('METRICS_EXPORT_URL'),
41
+
42
+ // Metric storage
43
+ retentionPeriod: config.number('METRICS_RETENTION_PERIOD', 3600000), // 1 hour in ms
44
+
45
+ maxDataPoints: config.number('METRICS_MAX_DATA_POINTS', 1000)
46
+ } as const
47
+
48
+ /**
49
+ * Profiling Configuration Schema
50
+ */
51
+ const profilingSchema = {
52
+ enabled: config.boolean('PROFILING_ENABLED', false),
53
+
54
+ sampleRate: {
55
+ type: 'number' as const,
56
+ env: 'PROFILING_SAMPLE_RATE',
57
+ default: helpers.isProduction() ? 0.01 : 0.1,
58
+ validate: (value: number) => {
59
+ if (value < 0 || value > 1) {
60
+ return 'Sample rate must be between 0 and 1'
61
+ }
62
+ return true
63
+ }
64
+ },
65
+
66
+ memoryProfiling: config.boolean('MEMORY_PROFILING', false),
67
+
68
+ cpuProfiling: config.boolean('CPU_PROFILING', false),
69
+
70
+ heapSnapshot: config.boolean('HEAP_SNAPSHOT', false),
71
+
72
+ // Profiling output
73
+ outputDir: config.string('PROFILING_OUTPUT_DIR', 'profiling'),
74
+
75
+ maxProfiles: config.number('PROFILING_MAX_PROFILES', 10)
76
+ } as const
77
+
78
+ /**
79
+ * Monitoring Configuration Schema
80
+ */
81
+ const monitoringSchema = {
82
+ enabled: config.boolean('ENABLE_MONITORING', false),
83
+
84
+ // Exporters
85
+ exporters: config.array('MONITORING_EXPORTERS', []),
86
+
87
+ // Health checks
88
+ enableHealthChecks: config.boolean('ENABLE_HEALTH_CHECKS', true),
89
+
90
+ healthCheckInterval: config.number('HEALTH_CHECK_INTERVAL', 30000), // 30s
91
+
92
+ // Alerting
93
+ enableAlerts: config.boolean('ENABLE_ALERTS', false),
94
+
95
+ alertWebhook: config.string('ALERT_WEBHOOK')
96
+ } as const
97
+
98
+ /**
99
+ * Export monitoring config (nested)
100
+ */
101
+ export const monitoringConfig = defineNestedConfig({
102
+ monitoring: monitoringSchema,
103
+ metrics: metricsSchema,
104
+ profiling: profilingSchema
105
+ })
106
+
107
+ // Export types
108
+ export type MonitoringConfig = typeof monitoringConfig.monitoring
109
+ export type MetricsConfig = typeof monitoringConfig.metrics
110
+ export type ProfilingConfig = typeof monitoringConfig.profiling
111
+ export type MonitoringFullConfig = typeof monitoringConfig
112
+
113
+ // Export default
114
+ export default monitoringConfig
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Plugins Configuration
3
+ * Declarative plugin management configuration
4
+ */
5
+
6
+ import { defineConfig, config } from '@/core/utils/config-schema'
7
+ import { env } from '@/core/utils/env'
8
+ import { FLUXSTACK_VERSION } from '@/core/utils/version'
9
+
10
+ /**
11
+ * Plugins configuration schema
12
+ */
13
+ const pluginsConfigSchema = {
14
+ // Plugin management
15
+ enabled: config.array(
16
+ 'FLUXSTACK_PLUGINS_ENABLED',
17
+ ['logger', 'swagger', 'vite', 'cors', 'static-files', 'crypto-auth']
18
+ ),
19
+
20
+ disabled: config.array('FLUXSTACK_PLUGINS_DISABLED', []),
21
+
22
+ // Auto-discovery
23
+ autoDiscover: config.boolean('PLUGINS_AUTO_DISCOVER', true),
24
+
25
+ pluginsDir: config.string('PLUGINS_DIR', 'plugins'),
26
+
27
+ // Plugin-specific configurations
28
+ // Logger plugin (handled by logger.config.ts)
29
+ loggerEnabled: config.boolean('LOGGER_PLUGIN_ENABLED', true),
30
+
31
+ // Swagger plugin (enable/disable via runtime.config.ts)
32
+ swaggerTitle: config.string('SWAGGER_TITLE', 'FluxStack API'),
33
+ swaggerVersion: config.string('SWAGGER_VERSION', FLUXSTACK_VERSION),
34
+ swaggerDescription: config.string(
35
+ 'SWAGGER_DESCRIPTION',
36
+ 'API documentation for FluxStack application'
37
+ ),
38
+ swaggerPath: config.string('SWAGGER_PATH', '/swagger'),
39
+
40
+ // Static files plugin
41
+ staticFilesEnabled: config.boolean('STATIC_FILES_ENABLED', true),
42
+ staticPublicDir: config.string('STATIC_PUBLIC_DIR', 'public'),
43
+ staticUploadsDir: config.string('STATIC_UPLOADS_DIR', 'uploads'),
44
+ staticCacheMaxAge: config.number('STATIC_CACHE_MAX_AGE', 31536000), // 1 year
45
+ staticEnableUploads: config.boolean('STATIC_ENABLE_UPLOADS', true),
46
+ staticEnablePublic: config.boolean('STATIC_ENABLE_PUBLIC', true),
47
+
48
+ // CORS plugin (configuration via server.config.ts)
49
+ // Vite plugin
50
+ viteEnabled: config.boolean('VITE_PLUGIN_ENABLED', true)
51
+ } as const
52
+
53
+ export const pluginsConfig = defineConfig(pluginsConfigSchema)
54
+
55
+ // Export type
56
+ export type PluginsConfig = typeof pluginsConfig
57
+
58
+ // Export default
59
+ export default pluginsConfig
@@ -16,19 +16,6 @@ export const appRuntimeConfig = defineReactiveConfig({
16
16
  enableMonitoring: config.boolean('ENABLE_MONITORING', false),
17
17
  enableDebugMode: config.boolean('DEBUG', false),
18
18
 
19
- // Logging level can be changed in runtime
20
- logLevel: config.enum(
21
- 'LOG_LEVEL',
22
- ['debug', 'info', 'warn', 'error'] as const,
23
- 'info'
24
- ),
25
-
26
- logFormat: config.enum(
27
- 'LOG_FORMAT',
28
- ['json', 'pretty'] as const,
29
- 'pretty'
30
- ),
31
-
32
19
  // Rate limiting
33
20
  rateLimitEnabled: config.boolean('RATE_LIMIT_ENABLED', true),
34
21
 
@@ -62,9 +49,6 @@ export const appRuntimeConfig = defineReactiveConfig({
62
49
  validate: (value: number) => value > 0 || 'Max upload size must be positive'
63
50
  },
64
51
 
65
- // Allowed origins (can be updated in runtime)
66
- corsOrigins: config.array('CORS_ORIGINS', ['*']),
67
-
68
52
  // Maintenance mode
69
53
  maintenanceMode: config.boolean('MAINTENANCE_MODE', false),
70
54
 
@@ -80,7 +64,6 @@ export const appRuntimeConfig = defineReactiveConfig({
80
64
  appRuntimeConfig.watch((newConfig) => {
81
65
  console.log('๐Ÿ”„ Runtime config reloaded:')
82
66
  console.log(' Debug:', newConfig.enableDebugMode)
83
- console.log(' Log Level:', newConfig.logLevel)
84
67
  console.log(' Maintenance:', newConfig.maintenanceMode)
85
68
  })
86
69
 
@@ -1,48 +1,68 @@
1
1
  /**
2
2
  * Server Configuration
3
- * Declarative server config using FluxStack config system
3
+ * Server-specific settings (port, host, CORS, middleware)
4
4
  */
5
5
 
6
- import { defineConfig, config } from '@/core/utils/config-schema'
7
- import { FLUXSTACK_VERSION } from '@/core/utils/version'
6
+ import { defineConfig, defineNestedConfig, config } from '@/core/utils/config-schema'
8
7
 
9
- const serverConfigSchema = {
8
+ /**
9
+ * CORS configuration schema
10
+ */
11
+ const corsSchema = {
12
+ origins: config.array('CORS_ORIGINS', ['http://localhost:3000', 'http://localhost:5173']),
13
+ methods: config.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
14
+ headers: config.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
15
+ credentials: config.boolean('CORS_CREDENTIALS', false),
16
+ maxAge: config.number('CORS_MAX_AGE', 86400)
17
+ } as const
18
+
19
+ /**
20
+ * Server configuration schema
21
+ */
22
+ const serverSchema = {
10
23
  // Server basics
11
- port: config.number('PORT', 3000, true),
12
- host: config.string('HOST', 'localhost', true),
13
- apiPrefix: config.string('API_PREFIX', '/api'),
24
+ port: {
25
+ type: 'number' as const,
26
+ env: 'PORT',
27
+ default: 3000,
28
+ required: true,
29
+ validate: (value: number) => {
30
+ if (value < 1 || value > 65535) {
31
+ return 'Port must be between 1 and 65535'
32
+ }
33
+ return true
34
+ }
35
+ },
14
36
 
15
- // CORS configuration
16
- corsOrigins: config.array('CORS_ORIGINS', ['http://localhost:3000', 'http://localhost:5173']),
17
- corsMethods: config.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
18
- corsHeaders: config.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
19
- corsCredentials: config.boolean('CORS_CREDENTIALS', false),
20
- corsMaxAge: config.number('CORS_MAX_AGE', 86400),
37
+ host: config.string('HOST', 'localhost', true),
21
38
 
22
- // Client config
23
- clientPort: config.number('VITE_PORT', 5173),
24
- clientTarget: config.string('CLIENT_TARGET', 'es2020'),
25
- clientOutDir: config.string('CLIENT_OUTDIR', 'dist'),
26
- clientSourceMaps: config.boolean('CLIENT_SOURCEMAPS', false),
39
+ apiPrefix: {
40
+ type: 'string' as const,
41
+ env: 'API_PREFIX',
42
+ default: '/api',
43
+ validate: (value: string) => value.startsWith('/') || 'API prefix must start with /'
44
+ },
27
45
 
28
46
  // Backend-only mode
29
47
  backendPort: config.number('BACKEND_PORT', 3001),
30
48
 
31
- // App info
32
- appName: config.string('FLUXSTACK_APP_NAME', 'FluxStack'),
33
- appVersion: config.string('FLUXSTACK_APP_VERSION', FLUXSTACK_VERSION),
34
-
35
49
  // Features
36
- enableSwagger: config.boolean('ENABLE_SWAGGER', true),
37
- enableMetrics: config.boolean('ENABLE_METRICS', false),
38
- enableMonitoring: config.boolean('ENABLE_MONITORING', false),
39
50
  enableRequestLogging: config.boolean('ENABLE_REQUEST_LOGGING', true),
40
-
41
- // Vite/Development
42
- enableViteProxyLogs: config.boolean('ENABLE_VITE_PROXY_LOGS', false)
51
+ showBanner: config.boolean('SHOW_SERVER_BANNER', true)
43
52
  } as const
44
53
 
45
- export const serverConfig = defineConfig(serverConfigSchema)
54
+ /**
55
+ * Export server config (nested with CORS)
56
+ */
57
+ export const serverConfig = defineNestedConfig({
58
+ server: serverSchema,
59
+ cors: corsSchema
60
+ })
61
+
62
+ // Export types
63
+ export type ServerConfig = typeof serverConfig.server
64
+ export type CorsConfig = typeof serverConfig.cors
65
+ export type ServerFullConfig = typeof serverConfig
46
66
 
47
- export type ServerConfig = typeof serverConfig
67
+ // Export default
48
68
  export default serverConfig
@@ -3,11 +3,13 @@ import { existsSync, mkdirSync } from "fs"
3
3
  import { join } from "path"
4
4
  import type { FluxStackConfig } from "../config"
5
5
  import type { BundleResult, BundleOptions } from "../types/build"
6
+ import { buildLogger } from "../utils/build-logger"
6
7
 
7
8
  export interface BundlerConfig {
8
9
  target: 'bun' | 'node' | 'docker'
9
10
  outDir: string
10
11
  sourceMaps: boolean
12
+ minify?: boolean
11
13
  external?: string[]
12
14
  }
13
15
 
@@ -19,8 +21,9 @@ export class Bundler {
19
21
  }
20
22
 
21
23
  async bundleClient(options: BundleOptions = {}): Promise<BundleResult> {
22
- console.log("โšก Bundling client...")
23
-
24
+ buildLogger.section('Client Build', 'โšก')
25
+ buildLogger.step('Starting Vite build...')
26
+
24
27
  const startTime = Date.now()
25
28
 
26
29
  try {
@@ -41,9 +44,9 @@ export class Bundler {
41
44
 
42
45
  const exitCode = await buildProcess.exited
43
46
  const duration = Date.now() - startTime
44
-
47
+
45
48
  if (exitCode === 0) {
46
- console.log("โœ… Client bundle completed")
49
+ buildLogger.success(`Client bundle completed in ${buildLogger.formatDuration(duration)}`)
47
50
  return {
48
51
  success: true,
49
52
  duration,
@@ -52,7 +55,7 @@ export class Bundler {
52
55
  }
53
56
  } else {
54
57
  const stderr = await new Response(buildProcess.stderr).text()
55
- console.error("โŒ Client bundle failed")
58
+ buildLogger.error("Client bundle failed")
56
59
  return {
57
60
  success: false,
58
61
  duration,
@@ -70,23 +73,21 @@ export class Bundler {
70
73
  }
71
74
 
72
75
  async bundleServer(entryPoint: string, options: BundleOptions = {}): Promise<BundleResult> {
73
- console.log("โšก Bundling server...")
74
-
76
+ buildLogger.section('Server Build', 'โšก')
77
+
75
78
  const startTime = Date.now()
76
79
  let liveComponentsGenerator: any = null
77
-
80
+
78
81
  try {
79
82
  // ๐Ÿš€ PRE-BUILD: Auto-generate Live Components registration
80
83
  const generatorModule = await import('./live-components-generator')
81
84
  liveComponentsGenerator = generatorModule.liveComponentsGenerator
82
85
  const discoveredComponents = await liveComponentsGenerator.preBuild()
83
- console.log(`๐Ÿ” Auto-discovered ${discoveredComponents.length} Live Components for bundle`)
84
-
86
+
85
87
  // ๐Ÿ”Œ PRE-BUILD: Auto-generate FluxStack Plugins registration
86
88
  const pluginsGeneratorModule = await import('./flux-plugins-generator')
87
89
  const fluxPluginsGenerator = pluginsGeneratorModule.fluxPluginsGenerator
88
90
  const discoveredPlugins = await fluxPluginsGenerator.preBuild()
89
- console.log(`๐Ÿ” Auto-discovered ${discoveredPlugins.length} FluxStack Plugins for bundle`)
90
91
 
91
92
  // Ensure output directory exists
92
93
  if (!existsSync(this.config.outDir)) {
@@ -130,12 +131,12 @@ export class Bundler {
130
131
 
131
132
  const exitCode = await buildProcess.exited
132
133
  const duration = Date.now() - startTime
133
-
134
+
134
135
  // ๐Ÿงน POST-BUILD: Handle auto-generated registration file
135
136
  // (liveComponentsGenerator already available from above)
136
-
137
+
137
138
  if (exitCode === 0) {
138
- console.log("โœ… Server bundle completed")
139
+ buildLogger.success(`Server bundle completed in ${buildLogger.formatDuration(duration)}`)
139
140
 
140
141
  // Keep generated files for production (they're now baked into bundle)
141
142
  await liveComponentsGenerator.postBuild(false)
@@ -152,7 +153,7 @@ export class Bundler {
152
153
  entryPoint: join(this.config.outDir, "index.js")
153
154
  }
154
155
  } else {
155
- console.error("โŒ Server bundle failed")
156
+ buildLogger.error("Server bundle failed")
156
157
 
157
158
  // Restore original files since build failed
158
159
  await liveComponentsGenerator.postBuild(false)
@@ -183,7 +184,7 @@ export class Bundler {
183
184
  const fluxPluginsGenerator = pluginsGeneratorModule.fluxPluginsGenerator
184
185
  await fluxPluginsGenerator.postBuild(false)
185
186
  } catch (cleanupError) {
186
- console.warn('โš ๏ธ Failed to cleanup generated files:', cleanupError)
187
+ buildLogger.warn(`Failed to cleanup generated files: ${cleanupError}`)
187
188
  }
188
189
 
189
190
  return {
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { existsSync, readdirSync, writeFileSync, unlinkSync, readFileSync, statSync } from 'fs'
5
5
  import { join, extname, basename } from 'path'
6
+ import { buildLogger } from '../utils/build-logger'
6
7
 
7
8
  export interface PluginInfo {
8
9
  pluginDir: string
@@ -36,8 +37,6 @@ export class FluxPluginsGenerator {
36
37
  if (existsSync(this.pluginsPath)) {
37
38
  const externalPlugins = this.discoverPluginsInDirectory(this.pluginsPath, 'external')
38
39
  plugins.push(...externalPlugins)
39
- } else {
40
- console.log('โš ๏ธ No external plugins directory found (plugins/)')
41
40
  }
42
41
 
43
42
  // Note: Built-in plugins are automatically loaded by core system
@@ -78,13 +77,13 @@ export class FluxPluginsGenerator {
78
77
  type
79
78
  })
80
79
 
81
- console.log(`๐Ÿ” Discovered ${type} plugin: ${entry} (${entryFile})`)
80
+ buildLogger.step(`Discovered ${type} plugin: ${entry} (${entryFile})`)
82
81
  } else {
83
- console.warn(`โš ๏ธ Plugin '${entry}' has no valid entry point`)
82
+ buildLogger.warn(`Plugin '${entry}' has no valid entry point`)
84
83
  }
85
84
  }
86
85
  } catch (error) {
87
- console.warn(`โš ๏ธ Failed to scan ${type} plugins directory '${directory}':`, error)
86
+ // Silently skip directories that can't be scanned
88
87
  }
89
88
 
90
89
  return plugins
@@ -122,7 +121,6 @@ export class FluxPluginsGenerator {
122
121
  if (existsSync(this.registrationFilePath)) {
123
122
  const existingContent = readFileSync(this.registrationFilePath, 'utf-8')
124
123
  writeFileSync(this.backupFilePath, existingContent)
125
- console.log('๐Ÿ“„ Backed up existing auto-registry.ts')
126
124
  }
127
125
 
128
126
  // All discovered plugins are external (built-in are handled by core)
@@ -198,7 +196,7 @@ console.log('๐Ÿ” Auto-discovered ${plugins.length} external plugins' + (pluginN
198
196
  `
199
197
 
200
198
  writeFileSync(this.registrationFilePath, fileContent)
201
- console.log(`โœ… Generated plugin registry with ${plugins.length} plugins`)
199
+ buildLogger.success(`Generated registry for ${plugins.length} plugins`)
202
200
  }
203
201
 
204
202
  /**
@@ -220,12 +218,10 @@ console.log('๐Ÿ” Auto-discovered ${plugins.length} external plugins' + (pluginN
220
218
  const backupContent = readFileSync(this.backupFilePath, 'utf-8')
221
219
  writeFileSync(this.registrationFilePath, backupContent)
222
220
  unlinkSync(this.backupFilePath)
223
- console.log('๐Ÿ”„ Restored original auto-registry.ts')
224
221
  } else {
225
222
  // If no backup exists, remove the generated file
226
223
  if (existsSync(this.registrationFilePath)) {
227
224
  unlinkSync(this.registrationFilePath)
228
- console.log('๐Ÿ—‘๏ธ Removed auto-generated registry file')
229
225
  }
230
226
  }
231
227
  }
@@ -246,17 +242,33 @@ console.log('๐Ÿ” Auto-discovered ${plugins.length} external plugins' + (pluginN
246
242
  * Pre-build hook: Generate registration file
247
243
  */
248
244
  async preBuild(): Promise<PluginInfo[]> {
249
- console.log('๐Ÿš€ [PRE-BUILD] Generating FluxStack Plugins registry...')
250
-
245
+ buildLogger.section('FluxStack Plugins Discovery', '๐Ÿ”Œ')
246
+
251
247
  const plugins = this.discoverPlugins()
252
-
248
+
253
249
  if (plugins.length === 0) {
254
- console.log('โš ๏ธ No FluxStack Plugins found to register')
250
+ buildLogger.warn('No FluxStack Plugins found')
255
251
  return []
256
252
  }
257
253
 
254
+ // Create table of discovered plugins
255
+ const pluginData = plugins.map(p => ({
256
+ plugin: p.pluginName,
257
+ type: p.type,
258
+ entry: p.entryFile
259
+ }))
260
+
261
+ buildLogger.table(
262
+ [
263
+ { header: 'Plugin', key: 'plugin', width: 25, align: 'left', color: 'cyan' },
264
+ { header: 'Type', key: 'type', width: 12, align: 'left', color: 'yellow' },
265
+ { header: 'Entry Point', key: 'entry', width: 20, align: 'left', color: 'gray' }
266
+ ],
267
+ pluginData
268
+ )
269
+
258
270
  this.generateRegistrationFile(plugins)
259
-
271
+
260
272
  return plugins
261
273
  }
262
274
 
@@ -264,10 +276,9 @@ console.log('๐Ÿ” Auto-discovered ${plugins.length} external plugins' + (pluginN
264
276
  * Post-build hook: Clean up generated file (optional)
265
277
  */
266
278
  async postBuild(keepGenerated: boolean = false): Promise<void> {
267
- console.log('๐Ÿงน [POST-BUILD] Cleaning up FluxStack Plugins registry...')
268
-
279
+ buildLogger.step('Cleaning up FluxStack Plugins registry...')
280
+
269
281
  if (keepGenerated) {
270
- console.log('๐Ÿ“ Keeping auto-generated plugin registry for production')
271
282
  // Remove backup since we're keeping the generated version
272
283
  if (existsSync(this.backupFilePath)) {
273
284
  unlinkSync(this.backupFilePath)
@@ -304,7 +315,7 @@ console.log('๐Ÿ” Auto-discovered ${plugins.length} external plugins' + (pluginN
304
315
  */
305
316
  updateIfNeeded(): void {
306
317
  if (this.needsUpdate()) {
307
- console.log('๐Ÿ”„ FluxStack Plugins changed, updating registry...')
318
+ buildLogger.info('FluxStack Plugins changed, updating registry...')
308
319
  const plugins = this.discoverPlugins()
309
320
  this.generateRegistrationFile(plugins)
310
321
  }