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.
- package/.dockerignore +82 -0
- package/Dockerfile +70 -0
- package/app/server/app.ts +20 -5
- package/app/server/backend-only.ts +15 -12
- package/app/server/index.ts +83 -96
- package/app/server/live/FluxStackConfig.ts +5 -5
- package/app/server/routes/env-test.ts +59 -0
- package/config/app.config.ts +2 -54
- package/config/client.config.ts +95 -0
- package/config/index.ts +57 -22
- package/config/monitoring.config.ts +114 -0
- package/config/plugins.config.ts +59 -0
- package/config/runtime.config.ts +0 -17
- package/config/server.config.ts +50 -30
- package/core/build/bundler.ts +17 -16
- package/core/build/flux-plugins-generator.ts +29 -18
- package/core/build/index.ts +32 -31
- package/core/build/live-components-generator.ts +29 -18
- package/core/build/optimizer.ts +37 -17
- package/core/cli/index.ts +6 -2
- package/core/config/env.ts +4 -0
- package/core/config/runtime-config.ts +10 -8
- package/core/config/schema.ts +24 -2
- package/core/framework/server.ts +1 -0
- package/core/index.ts +31 -23
- package/core/plugins/built-in/static/index.ts +73 -246
- package/core/plugins/built-in/vite/index.ts +377 -377
- package/core/plugins/registry.ts +22 -18
- package/core/server/backend-entry.ts +51 -0
- package/core/types/plugin.ts +6 -0
- package/core/utils/build-logger.ts +324 -0
- package/core/utils/config-schema.ts +2 -6
- package/core/utils/helpers.ts +14 -9
- package/core/utils/regenerate-files.ts +69 -0
- package/core/utils/version.ts +1 -1
- package/fluxstack.config.ts +138 -252
- package/package.json +2 -17
- package/vitest.config.ts +8 -26
- 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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
14
|
+
// Create backend configuration from declarative config
|
|
15
|
+
const backendConfig = createBackendConfig(serverConfig)
|
|
13
16
|
|
|
14
|
-
//
|
|
15
|
-
|
|
17
|
+
// Start backend in standalone mode
|
|
18
|
+
startBackend(appInstance, backendConfig)
|
package/app/server/index.ts
CHANGED
|
@@ -1,125 +1,112 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
11
|
+
|
|
12
|
+
// ===== Configuration =====
|
|
8
13
|
import { appConfig } from "@/config/app.config"
|
|
9
|
-
import {
|
|
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
|
-
//
|
|
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
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
//
|
|
78
|
+
// ===== Register Plugins =====
|
|
79
|
+
// Note: Logger is part of core, not a plugin
|
|
53
80
|
|
|
54
|
-
//
|
|
81
|
+
// 1. Authentication plugin (must be registered first)
|
|
55
82
|
app.use(cryptoAuthPlugin)
|
|
56
83
|
|
|
57
|
-
//
|
|
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
|
-
//
|
|
65
|
-
app.use(staticFilesPlugin)
|
|
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
|
-
//
|
|
70
|
-
app.
|
|
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
|
-
//
|
|
114
|
-
app.
|
|
97
|
+
// ===== Register Routes =====
|
|
98
|
+
// Note: Routes are now registered in app.ts (including envTestRoute)
|
|
99
|
+
app.routes(appInstance)
|
|
115
100
|
|
|
116
|
-
//
|
|
101
|
+
// ===== Final Setup =====
|
|
102
|
+
|
|
103
|
+
// Swagger documentation (must be last to discover all routes)
|
|
117
104
|
app.use(swaggerPlugin)
|
|
118
105
|
|
|
119
|
-
//
|
|
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
|
+
})
|
package/config/app.config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Application Configuration
|
|
3
|
-
*
|
|
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
|