create-fluxstack 1.7.4 → 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 (45) 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 +72 -65
  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/monitoring/index.ts +2 -0
  27. package/core/plugins/built-in/static/index.ts +73 -244
  28. package/core/plugins/built-in/swagger/index.ts +2 -0
  29. package/core/plugins/built-in/vite/index.ts +377 -374
  30. package/core/plugins/config.ts +2 -0
  31. package/core/plugins/discovery.ts +2 -0
  32. package/core/plugins/executor.ts +2 -0
  33. package/core/plugins/index.ts +2 -2
  34. package/core/plugins/registry.ts +22 -18
  35. package/core/server/backend-entry.ts +51 -0
  36. package/core/types/plugin.ts +6 -0
  37. package/core/utils/build-logger.ts +324 -0
  38. package/core/utils/config-schema.ts +2 -6
  39. package/core/utils/helpers.ts +14 -9
  40. package/core/utils/regenerate-files.ts +69 -0
  41. package/core/utils/version.ts +1 -1
  42. package/fluxstack.config.ts +138 -252
  43. package/package.json +2 -17
  44. package/vitest.config.ts +8 -26
  45. package/config/build.config.ts +0 -24
package/.dockerignore ADDED
@@ -0,0 +1,82 @@
1
+ # =====================================
2
+ # FluxStack Docker Ignore
3
+ # =====================================
4
+
5
+ # Node modules (will be installed in container)
6
+ node_modules/
7
+ **/node_modules/
8
+
9
+ # Build artifacts (will be built in container)
10
+ dist/
11
+ **/dist/
12
+
13
+ # Development files
14
+ .git/
15
+ .github/
16
+ .vscode/
17
+ .idea/
18
+
19
+ # Environment files
20
+ .env
21
+ .env.*
22
+ !.env.example
23
+
24
+ # Logs
25
+ logs/
26
+ *.log
27
+ npm-debug.log*
28
+ yarn-debug.log*
29
+ yarn-error.log*
30
+ bun-debug.log*
31
+ lerna-debug.log*
32
+
33
+ # Testing
34
+ coverage/
35
+ .nyc_output/
36
+ **/__tests__/
37
+ **/*.test.ts
38
+ **/*.test.tsx
39
+ **/*.spec.ts
40
+ **/*.spec.tsx
41
+
42
+ # Documentation
43
+ *.md
44
+ !README.md
45
+ ai-context/
46
+ docs/
47
+
48
+ # Development tools
49
+ .eslintrc*
50
+ .prettierrc*
51
+ tsconfig*.json
52
+ vitest.config.ts
53
+ vite.config.ts
54
+
55
+ # OS files
56
+ .DS_Store
57
+ Thumbs.db
58
+
59
+ # Temporary files
60
+ tmp/
61
+ temp/
62
+ *.tmp
63
+ *.swp
64
+ *.swo
65
+ *~
66
+
67
+ # Lock files (exclude other package managers, keep bun.lock)
68
+ package-lock.json
69
+ yarn.lock
70
+ pnpm-lock.yaml
71
+
72
+ # CI/CD
73
+ .github/
74
+
75
+ # Editor directories
76
+ .vscode/
77
+ .idea/
78
+ *.suo
79
+ *.ntvs*
80
+ *.njsproj
81
+ *.sln
82
+ *.sw?
package/Dockerfile ADDED
@@ -0,0 +1,70 @@
1
+ # 🐳 FluxStack Production Dockerfile
2
+ # Multi-stage build for optimized production image
3
+
4
+ # =====================================
5
+ # Stage 1: Dependencies
6
+ # =====================================
7
+ FROM oven/bun:1.1.34-alpine AS deps
8
+
9
+ WORKDIR /app
10
+
11
+ # Copy package files
12
+ COPY package.json bun.lock ./
13
+
14
+ # Install production dependencies only
15
+ RUN bun install --production --frozen-lockfile
16
+
17
+ # =====================================
18
+ # Stage 2: Builder
19
+ # =====================================
20
+ FROM oven/bun:1.1.34-alpine AS builder
21
+
22
+ WORKDIR /app
23
+
24
+ # Copy package files and install all dependencies (including dev)
25
+ COPY package.json bun.lock ./
26
+ RUN bun install --frozen-lockfile
27
+
28
+ # Copy source code
29
+ COPY . .
30
+
31
+ # Build the application
32
+ RUN bun run build
33
+
34
+ # =====================================
35
+ # Stage 3: Production Runner
36
+ # =====================================
37
+ FROM oven/bun:1.1.34-alpine AS runner
38
+
39
+ WORKDIR /app
40
+
41
+ # Set production environment
42
+ ENV NODE_ENV=production
43
+ ENV PORT=3000
44
+
45
+ # Create non-root user for security
46
+ RUN addgroup -g 1001 -S fluxstack && \
47
+ adduser -S fluxstack -u 1001
48
+
49
+ # Copy production dependencies from deps stage
50
+ COPY --from=deps --chown=fluxstack:fluxstack /app/node_modules ./node_modules
51
+
52
+ # Copy built application from builder stage
53
+ COPY --from=builder --chown=fluxstack:fluxstack /app/dist ./dist
54
+ COPY --from=builder --chown=fluxstack:fluxstack /app/package.json ./
55
+
56
+ # Copy config directory (required for runtime configuration)
57
+ COPY --from=builder --chown=fluxstack:fluxstack /app/config ./config
58
+
59
+ # Switch to non-root user
60
+ USER fluxstack
61
+
62
+ # Expose application port
63
+ EXPOSE 3000
64
+
65
+ # Health check disabled for now
66
+ # HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
67
+ # CMD bun run -e 'fetch("http://localhost:3000/api/health").then(r => r.ok ? process.exit(0) : process.exit(1))' || exit 1
68
+
69
+ # Start the application
70
+ CMD ["bun", "run", "start"]
package/app/server/app.ts CHANGED
@@ -1,10 +1,25 @@
1
- // Export the main app type for Eden Treaty
2
- import { apiRoutes } from "./routes"
1
+ /**
2
+ * 🎯 Application Instance - Single Source of Truth
3
+ *
4
+ * This instance is used by:
5
+ * - index.ts (full-stack mode)
6
+ * - backend-only.ts (backend standalone mode)
7
+ * - Eden Treaty client (type inference)
8
+ *
9
+ * This ensures that the type exported for Eden Treaty is exactly
10
+ * the same as what the server uses.
11
+ */
12
+
3
13
  import { Elysia } from "elysia"
14
+ import { apiRoutes } from "./routes"
15
+ import { envTestRoute } from "./routes/env-test"
4
16
 
5
- // Create the full app structure that matches the server
6
- const appInstance = new Elysia()
7
- .use(apiRoutes)
17
+ /**
18
+ * Main application instance with all routes registered
19
+ */
20
+ export const appInstance = new Elysia()
21
+ .use(envTestRoute) // Environment test/debug endpoint
22
+ .use(apiRoutes) // Main application routes
8
23
 
9
24
  // Export the type correctly for Eden Treaty
10
25
  export type App = typeof appInstance
@@ -1,15 +1,18 @@
1
- // Backend standalone entry point
2
- import { startBackendOnly } from "@/core/server/standalone"
3
- import { apiRoutes } from "./routes"
4
- import { serverConfig } from "@/config/server.config"
1
+ /**
2
+ * Backend Standalone Entry Point
3
+ *
4
+ * This is a minimal wrapper for starting the backend in standalone mode.
5
+ * The core logic is protected in @/core/server/backend-entry.ts
6
+ *
7
+ * You can customize the configuration here if needed.
8
+ */
5
9
 
6
- // Configuração para backend standalone usando config declarativo
7
- const backendConfig = {
8
- port: serverConfig.backendPort,
9
- apiPrefix: serverConfig.apiPrefix
10
- }
10
+ import { startBackend, createBackendConfig } from "@/core/server/backend-entry"
11
+ import { appInstance } from "./app"
12
+ import { serverConfig } from "@/config/server.config"
11
13
 
12
- console.log(`🚀 Backend standalone: ${serverConfig.host}:${backendConfig.port}`)
14
+ // Create backend configuration from declarative config
15
+ const backendConfig = createBackendConfig(serverConfig)
13
16
 
14
- // Iniciar apenas o backend
15
- startBackendOnly(apiRoutes, backendConfig)
17
+ // Start backend in standalone mode
18
+ startBackend(appInstance, backendConfig)
@@ -1,125 +1,112 @@
1
- // User application entry point
2
- import { FluxStackFramework, vitePlugin, swaggerPlugin, staticPlugin, liveComponentsPlugin, staticFilesPlugin } from "@/core/server"
1
+ /**
2
+ * 🚀 FluxStack Application Server Entry Point
3
+ * Main server configuration and initialization
4
+ */
5
+
6
+ // ===== Core Framework =====
7
+ import { FluxStackFramework } from "@/core/server"
3
8
  import { isDevelopment } from "@/core/utils/helpers"
4
9
  import { DEBUG } from "@/core/utils/logger"
5
- import { apiRoutes } from "./routes"
6
10
  import { helpers } from "@/core/utils/env"
7
- import { serverConfig } from "@/config/server.config"
11
+
12
+ // ===== Configuration =====
8
13
  import { appConfig } from "@/config/app.config"
9
- import { loggerConfig } from "@/config/logger.config"
14
+ import { serverConfig } from "@/config/server.config"
15
+
16
+ // ===== Plugins =====
17
+ import {
18
+ vitePlugin,
19
+ swaggerPlugin,
20
+ staticPlugin,
21
+ liveComponentsPlugin,
22
+ staticFilesPlugin
23
+ } from "@/core/server"
10
24
  import cryptoAuthPlugin from "@/plugins/crypto-auth"
11
- import "./live/register-components"
12
25
 
13
- // Startup info moved to DEBUG level (set LOG_LEVEL=debug to see details)
26
+ // ===== Application Routes =====
27
+ import { appInstance } from "./app"
28
+
29
+ // NOTE: Live Components auto-discovery is handled by liveComponentsPlugin
30
+ // No need to import "./live/register-components" anymore
31
+
32
+ // ===== Startup Logging =====
14
33
  DEBUG('🔧 Loading declarative configuration...')
15
34
  DEBUG(`📊 Environment: ${appConfig.env}`)
16
- DEBUG(`🚀 Port: ${serverConfig.port}`)
17
- DEBUG(`🌐 Host: ${serverConfig.host}`)
18
-
19
- // Criar aplicação com configuração declarativa
20
- const app = new FluxStackFramework({
21
- server: {
22
- port: serverConfig.port,
23
- host: serverConfig.host,
24
- apiPrefix: serverConfig.apiPrefix,
25
- cors: {
26
- origins: serverConfig.corsOrigins,
27
- methods: serverConfig.corsMethods,
28
- headers: serverConfig.corsHeaders,
29
- credentials: serverConfig.corsCredentials
35
+ DEBUG(`🚀 Port: ${serverConfig.server.port}`)
36
+ DEBUG(`🌐 Host: ${serverConfig.server.host}`)
37
+
38
+ // ===== Framework Configuration Helper =====
39
+ /**
40
+ * Creates FluxStack framework configuration from declarative configs
41
+ */
42
+ function createFrameworkConfig() {
43
+ return {
44
+ server: {
45
+ port: serverConfig.server.port,
46
+ host: serverConfig.server.host,
47
+ apiPrefix: serverConfig.server.apiPrefix,
48
+ cors: {
49
+ origins: serverConfig.cors.origins,
50
+ methods: serverConfig.cors.methods,
51
+ headers: serverConfig.cors.headers,
52
+ credentials: serverConfig.cors.credentials
53
+ },
54
+ middleware: []
30
55
  },
31
- middleware: []
32
- },
33
- app: {
34
- name: serverConfig.appName,
35
- version: serverConfig.appVersion
36
- },
37
- client: {
38
- port: serverConfig.clientPort,
39
- proxy: {
40
- target: helpers.getServerUrl()
56
+ app: {
57
+ name: appConfig.name,
58
+ version: appConfig.version
41
59
  },
42
- build: {
43
- sourceMaps: serverConfig.clientSourceMaps,
44
- minify: false,
45
- target: serverConfig.clientTarget as any,
46
- outDir: serverConfig.clientOutDir
60
+ client: {
61
+ port: serverConfig.server.backendPort,
62
+ proxy: {
63
+ target: helpers.getServerUrl()
64
+ },
65
+ build: {
66
+ sourceMaps: false,
67
+ minify: false,
68
+ target: 'es2020' as any,
69
+ outDir: 'dist'
70
+ }
47
71
  }
48
72
  }
49
- })
73
+ }
50
74
 
75
+ // ===== Initialize Application =====
76
+ const app = new FluxStackFramework(createFrameworkConfig())
51
77
 
52
- // Usar plugins de infraestrutura primeiro (Logger é core, não é plugin)
78
+ // ===== Register Plugins =====
79
+ // Note: Logger is part of core, not a plugin
53
80
 
54
- // Registrar plugin de autenticação ANTES dos outros plugins
81
+ // 1. Authentication plugin (must be registered first)
55
82
  app.use(cryptoAuthPlugin)
56
83
 
57
- // Usar plugins condicionalmente baseado no ambiente
84
+ // 2. Development/Production plugins (conditional)
58
85
  if (isDevelopment()) {
59
- app.use(vitePlugin)
86
+ app.use(vitePlugin) // Development: Vite dev server
60
87
  } else {
61
- app.use(staticPlugin)
88
+ app.use(staticPlugin) // Production: Static file serving
62
89
  }
63
90
 
64
- // Add static files AFTER Vite to avoid conflicts, but BEFORE Live Components
65
- app.use(staticFilesPlugin) // Add Static Files support
66
- app.use(liveComponentsPlugin) // Add Live Components support
67
-
91
+ // 3. Static files (after Vite, before Live Components to avoid conflicts)
92
+ app.use(staticFilesPlugin)
68
93
 
69
- // Adicionar rota de teste para mostrar config declarativo (antes das rotas)
70
- app.getApp().get('/api/env-test', () => {
71
- return {
72
- message: '⚡ Declarative Config System!',
73
- timestamp: new Date().toISOString(),
74
- serverConfig: {
75
- port: serverConfig.port,
76
- host: serverConfig.host,
77
- apiPrefix: serverConfig.apiPrefix,
78
- appName: serverConfig.appName,
79
- appVersion: serverConfig.appVersion,
80
- cors: {
81
- origins: serverConfig.corsOrigins,
82
- methods: serverConfig.corsMethods,
83
- credentials: serverConfig.corsCredentials
84
- },
85
- client: {
86
- port: serverConfig.clientPort,
87
- target: serverConfig.clientTarget,
88
- sourceMaps: serverConfig.clientSourceMaps
89
- },
90
- features: {
91
- enableSwagger: serverConfig.enableSwagger,
92
- enableMetrics: serverConfig.enableMetrics,
93
- enableMonitoring: serverConfig.enableMonitoring
94
- }
95
- },
96
- environment: {
97
- NODE_ENV: appConfig.env,
98
- DEBUG: appConfig.debug,
99
- LOG_LEVEL: loggerConfig.level
100
- },
101
- urls: {
102
- server: helpers.getServerUrl(),
103
- client: helpers.getClientUrl(),
104
- swagger: `${helpers.getServerUrl()}/swagger`
105
- },
106
- system: {
107
- version: 'declarative-config',
108
- features: ['type-safe', 'validated', 'declarative', 'runtime-reload']
109
- }
110
- }
111
- })
94
+ // 4. Live Components (WebSocket support)
95
+ app.use(liveComponentsPlugin)
112
96
 
113
- // Registrar rotas da aplicação DEPOIS da rota de teste
114
- app.routes(apiRoutes)
97
+ // ===== Register Routes =====
98
+ // Note: Routes are now registered in app.ts (including envTestRoute)
99
+ app.routes(appInstance)
115
100
 
116
- // Swagger por último para descobrir todas as rotas
101
+ // ===== Final Setup =====
102
+
103
+ // Swagger documentation (must be last to discover all routes)
117
104
  app.use(swaggerPlugin)
118
105
 
119
- // Iniciar servidor (banner displayed by framework)
106
+ // ===== Start Server =====
107
+ // Banner will be displayed automatically by the framework
120
108
  app.listen()
121
109
 
122
-
123
-
124
- // Exportar tipo da aplicação para Eden Treaty (método correto)
110
+ // ===== Eden Treaty Type Export =====
111
+ // Export application type for type-safe client communication
125
112
  export type App = typeof app
@@ -160,9 +160,9 @@ export class FluxStackConfig extends LiveComponent<FluxStackConfigState> {
160
160
  // Set default state with real configuration
161
161
  this.state = {
162
162
  environment: appConfig.env,
163
- port: serverConfig.port,
164
- host: serverConfig.host,
165
- apiPrefix: serverConfig.apiPrefix,
163
+ port: serverConfig.server.port,
164
+ host: serverConfig.server.host,
165
+ apiPrefix: serverConfig.server.apiPrefix,
166
166
 
167
167
  framework: {
168
168
  name: 'FluxStack',
@@ -439,8 +439,8 @@ export class FluxStackConfig extends LiveComponent<FluxStackConfigState> {
439
439
  async getEnvironmentVariables() {
440
440
  const envVars = {
441
441
  NODE_ENV: appConfig.env,
442
- PORT: serverConfig.port.toString(),
443
- HOST: serverConfig.host,
442
+ PORT: serverConfig.server.port.toString(),
443
+ HOST: serverConfig.server.host,
444
444
  LOG_LEVEL: loggerConfig.level,
445
445
  // Add other non-sensitive env vars from system config
446
446
  PWD: systemConfig.pwd || undefined,
@@ -0,0 +1,59 @@
1
+ /**
2
+ * 🔧 Environment Test Route
3
+ * Displays current configuration for debugging purposes
4
+ */
5
+
6
+ import { Elysia } from 'elysia'
7
+ import { appConfig } from '@/config/app.config'
8
+ import { serverConfig } from '@/config/server.config'
9
+ import { loggerConfig } from '@/config/logger.config'
10
+ import { appRuntimeConfig } from '@/config/runtime.config'
11
+ import { helpers } from '@/core/utils/env'
12
+
13
+ /**
14
+ * Environment test endpoint
15
+ * Shows declarative config system information
16
+ */
17
+ export const envTestRoute = new Elysia({ prefix: '/api' })
18
+ .get('/env-test', () => {
19
+ return {
20
+ message: '⚡ Declarative Config System!',
21
+ timestamp: new Date().toISOString(),
22
+ serverConfig: {
23
+ port: serverConfig.server.port,
24
+ host: serverConfig.server.host,
25
+ apiPrefix: serverConfig.server.apiPrefix,
26
+ appName: appConfig.name,
27
+ appVersion: appConfig.version,
28
+ cors: {
29
+ origins: serverConfig.cors.origins,
30
+ methods: serverConfig.cors.methods,
31
+ credentials: serverConfig.cors.credentials
32
+ },
33
+ client: {
34
+ port: serverConfig.server.backendPort,
35
+ target: 'es2020',
36
+ sourceMaps: false
37
+ },
38
+ features: {
39
+ enableSwagger: appRuntimeConfig.values.enableSwagger,
40
+ enableMetrics: appRuntimeConfig.values.enableMetrics,
41
+ enableMonitoring: appRuntimeConfig.values.enableMonitoring
42
+ }
43
+ },
44
+ environment: {
45
+ NODE_ENV: appConfig.env,
46
+ DEBUG: appRuntimeConfig.values.enableDebugMode,
47
+ LOG_LEVEL: loggerConfig.level
48
+ },
49
+ urls: {
50
+ server: helpers.getServerUrl(),
51
+ client: helpers.getClientUrl(),
52
+ swagger: `${helpers.getServerUrl()}/swagger`
53
+ },
54
+ system: {
55
+ version: 'declarative-config',
56
+ features: ['type-safe', 'validated', 'declarative', 'runtime-reload']
57
+ }
58
+ }
59
+ })
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Application Configuration
3
- * Laravel-style declarative config with validation
3
+ * Core application metadata and global settings
4
4
  */
5
5
 
6
6
  import { defineConfig, config } from '@/core/utils/config-schema'
@@ -8,6 +8,7 @@ import { FLUXSTACK_VERSION } from '@/core/utils/version'
8
8
 
9
9
  /**
10
10
  * App configuration schema
11
+ * Contains only app-level metadata and global feature flags
11
12
  */
12
13
  const appConfigSchema = {
13
14
  // App basics
@@ -25,52 +26,9 @@ const appConfigSchema = {
25
26
  // Environment
26
27
  env: config.enum('NODE_ENV', ['development', 'production', 'test'] as const, 'development', true),
27
28
 
28
- debug: config.boolean('DEBUG', false),
29
-
30
- // Server
31
- port: {
32
- type: 'number' as const,
33
- env: 'PORT',
34
- default: 3000,
35
- required: true,
36
- validate: (value: number) => {
37
- if (value < 1 || value > 65535) {
38
- return 'Port must be between 1 and 65535'
39
- }
40
- return true
41
- }
42
- },
43
-
44
- host: config.string('HOST', 'localhost', true),
45
-
46
- apiPrefix: {
47
- type: 'string' as const,
48
- env: 'API_PREFIX',
49
- default: '/api',
50
- validate: (value: string) => value.startsWith('/') || 'API prefix must start with /'
51
- },
52
-
53
29
  // URLs
54
30
  url: config.string('APP_URL', undefined, false),
55
31
 
56
- // Features
57
- enableSwagger: config.boolean('ENABLE_SWAGGER', true),
58
- enableMetrics: config.boolean('ENABLE_METRICS', false),
59
- enableMonitoring: config.boolean('ENABLE_MONITORING', false),
60
-
61
- // Client
62
- clientPort: config.number('VITE_PORT', 5173),
63
-
64
- // Logging
65
- logLevel: config.enum('LOG_LEVEL', ['debug', 'info', 'warn', 'error'] as const, 'info'),
66
- logFormat: config.enum('LOG_FORMAT', ['json', 'pretty'] as const, 'pretty'),
67
-
68
- // CORS
69
- corsOrigins: config.array('CORS_ORIGINS', ['*']),
70
- corsMethods: config.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
71
- corsHeaders: config.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
72
- corsCredentials: config.boolean('CORS_CREDENTIALS', false),
73
-
74
32
  // Security
75
33
  trustProxy: config.boolean('TRUST_PROXY', false),
76
34
 
@@ -100,15 +58,5 @@ export type AppConfig = typeof appConfig
100
58
  */
101
59
  export type Environment = typeof appConfig.env
102
60
 
103
- /**
104
- * Type-safe log level type
105
- */
106
- export type LogLevel = typeof appConfig.logLevel
107
-
108
- /**
109
- * Type-safe log format type
110
- */
111
- export type LogFormat = typeof appConfig.logFormat
112
-
113
61
  // Export default
114
62
  export default appConfig
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Client & Vite Configuration
3
+ * Declarative client, proxy and Vite dev server configuration
4
+ */
5
+
6
+ import { defineConfig, defineNestedConfig, config } from '@/core/utils/config-schema'
7
+ import { env, helpers } from '@/core/utils/env'
8
+
9
+ /**
10
+ * Vite Dev Server Configuration
11
+ */
12
+ const viteSchema = {
13
+ port: config.number('VITE_PORT', 5173, true),
14
+
15
+ host: config.string('VITE_HOST', 'localhost'),
16
+
17
+ strictPort: config.boolean('VITE_STRICT_PORT', false),
18
+
19
+ open: config.boolean('VITE_OPEN', false),
20
+
21
+ enableLogging: config.boolean('ENABLE_VITE_PROXY_LOGS', false)
22
+ } as const
23
+
24
+ /**
25
+ * API Proxy Configuration
26
+ */
27
+ const proxySchema = {
28
+ target: {
29
+ type: 'string' as const,
30
+ env: 'PROXY_TARGET',
31
+ default: helpers.getServerUrl(),
32
+ required: false,
33
+ validate: (value: string) => {
34
+ if (!value) return true
35
+ try {
36
+ new URL(value)
37
+ return true
38
+ } catch {
39
+ return 'Proxy target must be a valid URL'
40
+ }
41
+ }
42
+ },
43
+
44
+ changeOrigin: config.boolean('PROXY_CHANGE_ORIGIN', true),
45
+
46
+ secure: config.boolean('PROXY_SECURE', false),
47
+
48
+ ws: config.boolean('PROXY_WS', true), // WebSocket support
49
+
50
+ rewrite: {
51
+ type: 'object' as const,
52
+ env: 'PROXY_REWRITE',
53
+ default: {},
54
+ required: false
55
+ }
56
+ } as const
57
+
58
+ /**
59
+ * Client Build Configuration
60
+ */
61
+ const buildSchema = {
62
+ outDir: config.string('CLIENT_OUTDIR', 'dist/client'),
63
+
64
+ sourceMaps: config.boolean('CLIENT_SOURCEMAPS', helpers.isDevelopment()),
65
+
66
+ minify: config.boolean('CLIENT_MINIFY', helpers.isProduction()),
67
+
68
+ target: config.string('CLIENT_TARGET', 'esnext'),
69
+
70
+ assetsDir: config.string('CLIENT_ASSETS_DIR', 'assets'),
71
+
72
+ cssCodeSplit: config.boolean('CLIENT_CSS_CODE_SPLIT', true),
73
+
74
+ chunkSizeWarningLimit: config.number('CLIENT_CHUNK_SIZE_WARNING', 500), // KB
75
+
76
+ emptyOutDir: config.boolean('CLIENT_EMPTY_OUTDIR', true)
77
+ } as const
78
+
79
+ /**
80
+ * Client Configuration (nested)
81
+ */
82
+ export const clientConfig = defineNestedConfig({
83
+ vite: viteSchema,
84
+ proxy: proxySchema,
85
+ build: buildSchema
86
+ })
87
+
88
+ // Export types
89
+ export type ViteConfig = typeof clientConfig.vite
90
+ export type ProxyConfig = typeof clientConfig.proxy
91
+ export type ClientBuildConfig = typeof clientConfig.build
92
+ export type ClientConfig = typeof clientConfig
93
+
94
+ // Export default
95
+ export default clientConfig