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/core/build/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { BuildResult, BuildManifest } from "../types/build"
|
|
|
5
5
|
import { Bundler } from "./bundler"
|
|
6
6
|
import { Optimizer } from "./optimizer"
|
|
7
7
|
import { FLUXSTACK_VERSION } from "../utils/version"
|
|
8
|
+
import { buildLogger } from "../utils/build-logger"
|
|
8
9
|
|
|
9
10
|
export class FluxStackBuilder {
|
|
10
11
|
private config: FluxStackConfig
|
|
@@ -19,6 +20,7 @@ export class FluxStackBuilder {
|
|
|
19
20
|
target: config.build.target,
|
|
20
21
|
outDir: config.build.outDir,
|
|
21
22
|
sourceMaps: config.build.sourceMaps,
|
|
23
|
+
minify: config.build.minify,
|
|
22
24
|
external: config.build.external
|
|
23
25
|
})
|
|
24
26
|
|
|
@@ -46,18 +48,18 @@ export class FluxStackBuilder {
|
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
async createDockerFiles() {
|
|
49
|
-
|
|
51
|
+
buildLogger.section('Docker Configuration', 'π³')
|
|
50
52
|
|
|
51
53
|
const distDir = this.config.build.outDir
|
|
52
|
-
|
|
54
|
+
buildLogger.step(`Output directory: ${distDir}`)
|
|
53
55
|
|
|
54
56
|
// Ensure dist directory exists
|
|
55
57
|
if (!existsSync(distDir)) {
|
|
56
|
-
|
|
58
|
+
buildLogger.step(`Creating directory: ${distDir}`)
|
|
57
59
|
mkdirSync(distDir, { recursive: true })
|
|
58
|
-
|
|
60
|
+
buildLogger.success('Directory created successfully')
|
|
59
61
|
} else {
|
|
60
|
-
|
|
62
|
+
buildLogger.success('Directory already exists')
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
// Dockerfile optimizado para produΓ§Γ£o
|
|
@@ -156,14 +158,14 @@ coverage
|
|
|
156
158
|
|
|
157
159
|
// Escrever arquivos no dist
|
|
158
160
|
try {
|
|
159
|
-
|
|
161
|
+
buildLogger.step('Writing Dockerfile...')
|
|
160
162
|
writeFileSync(join(distDir, "Dockerfile"), dockerfile)
|
|
161
|
-
|
|
163
|
+
buildLogger.step('Writing docker-compose.yml...')
|
|
162
164
|
writeFileSync(join(distDir, "docker-compose.yml"), dockerCompose)
|
|
163
|
-
|
|
165
|
+
buildLogger.step('Writing .dockerignore...')
|
|
164
166
|
writeFileSync(join(distDir, ".dockerignore"), dockerignore)
|
|
165
167
|
} catch (error) {
|
|
166
|
-
|
|
168
|
+
buildLogger.error(`Error writing Docker files: ${error}`)
|
|
167
169
|
throw error
|
|
168
170
|
}
|
|
169
171
|
|
|
@@ -172,13 +174,9 @@ coverage
|
|
|
172
174
|
const envExamplePath = join(process.cwd(), '.env.example')
|
|
173
175
|
const distEnvPath = join(distDir, ".env")
|
|
174
176
|
|
|
175
|
-
|
|
176
|
-
console.log(` - .env path: ${envPath}`)
|
|
177
|
-
console.log(` - .env.example path: ${envExamplePath}`)
|
|
178
|
-
console.log(` - target path: ${distEnvPath}`)
|
|
177
|
+
buildLogger.step('Configuring environment files...')
|
|
179
178
|
|
|
180
179
|
if (existsSync(envPath)) {
|
|
181
|
-
console.log(`π Copying .env file and setting production mode...`)
|
|
182
180
|
// Read .env content
|
|
183
181
|
let envContent = readFileSync(envPath, 'utf-8')
|
|
184
182
|
// Replace development with production
|
|
@@ -186,13 +184,11 @@ coverage
|
|
|
186
184
|
envContent = envContent.replace(/VITE_NODE_ENV=development/g, 'VITE_NODE_ENV=production')
|
|
187
185
|
// Write to dist
|
|
188
186
|
writeFileSync(distEnvPath, envContent)
|
|
189
|
-
|
|
187
|
+
buildLogger.success("Environment file copied (NODE_ENV=production)")
|
|
190
188
|
} else if (existsSync(envExamplePath)) {
|
|
191
|
-
console.log(`π Copying .env.example file...`)
|
|
192
189
|
copyFileSync(envExamplePath, distEnvPath)
|
|
193
|
-
|
|
190
|
+
buildLogger.success("Example environment file copied")
|
|
194
191
|
} else {
|
|
195
|
-
console.log(`π Creating default .env file...`)
|
|
196
192
|
// Criar um .env bΓ‘sico para produΓ§Γ£o
|
|
197
193
|
const defaultEnv = `NODE_ENV=production
|
|
198
194
|
PORT=3000
|
|
@@ -202,22 +198,20 @@ LOG_LEVEL=info
|
|
|
202
198
|
MONITORING_ENABLED=true
|
|
203
199
|
`
|
|
204
200
|
writeFileSync(distEnvPath, defaultEnv)
|
|
205
|
-
|
|
201
|
+
buildLogger.success("Default environment file created")
|
|
206
202
|
}
|
|
207
203
|
|
|
208
204
|
// Copy package.json for Docker build
|
|
209
205
|
const packageJsonPath = join(process.cwd(), 'package.json')
|
|
210
206
|
const distPackageJsonPath = join(distDir, 'package.json')
|
|
211
207
|
|
|
212
|
-
|
|
213
|
-
console.log(` - source: ${packageJsonPath}`)
|
|
214
|
-
console.log(` - target: ${distPackageJsonPath}`)
|
|
208
|
+
buildLogger.step('Copying package.json...')
|
|
215
209
|
|
|
216
210
|
if (existsSync(packageJsonPath)) {
|
|
217
211
|
copyFileSync(packageJsonPath, distPackageJsonPath)
|
|
218
|
-
|
|
212
|
+
buildLogger.success("Package.json copied successfully")
|
|
219
213
|
} else {
|
|
220
|
-
|
|
214
|
+
buildLogger.warn("package.json not found, creating minimal version...")
|
|
221
215
|
const minimalPackageJson = {
|
|
222
216
|
name: "fluxstack-app",
|
|
223
217
|
version: "1.0.0",
|
|
@@ -230,12 +224,13 @@ MONITORING_ENABLED=true
|
|
|
230
224
|
writeFileSync(distPackageJsonPath, JSON.stringify(minimalPackageJson, null, 2))
|
|
231
225
|
}
|
|
232
226
|
|
|
233
|
-
|
|
227
|
+
buildLogger.success("Docker configuration completed")
|
|
234
228
|
}
|
|
235
229
|
|
|
236
230
|
|
|
237
231
|
async build(): Promise<BuildResult> {
|
|
238
|
-
|
|
232
|
+
buildLogger.header('β‘ FluxStack Build')
|
|
233
|
+
buildLogger.startTimer()
|
|
239
234
|
|
|
240
235
|
const startTime = Date.now()
|
|
241
236
|
|
|
@@ -292,9 +287,15 @@ MONITORING_ENABLED=true
|
|
|
292
287
|
|
|
293
288
|
const duration = Date.now() - startTime
|
|
294
289
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
290
|
+
// Print build summary
|
|
291
|
+
buildLogger.summary('Build Completed Successfully', [
|
|
292
|
+
{ label: 'Build Time', value: buildLogger.formatDuration(duration), highlight: true },
|
|
293
|
+
{ label: 'Output Directory', value: this.config.build.outDir },
|
|
294
|
+
{ label: 'Client Assets', value: clientResult.assets?.length || 0 },
|
|
295
|
+
{ label: 'Total Size', value: buildLogger.formatSize(optimizationResult?.optimizedSize || 0) },
|
|
296
|
+
{ label: 'Compression', value: optimizationResult?.compressionRatio ? `${optimizationResult.compressionRatio.toFixed(2)}%` : 'N/A' },
|
|
297
|
+
{ label: 'Docker Ready', value: 'β', highlight: true }
|
|
298
|
+
])
|
|
298
299
|
|
|
299
300
|
return {
|
|
300
301
|
success: true,
|
|
@@ -316,7 +317,7 @@ MONITORING_ENABLED=true
|
|
|
316
317
|
const duration = Date.now() - startTime
|
|
317
318
|
const errorMessage = error instanceof Error ? error.message : "Unknown build error"
|
|
318
319
|
|
|
319
|
-
|
|
320
|
+
buildLogger.error(`Build failed: ${errorMessage}`)
|
|
320
321
|
|
|
321
322
|
return {
|
|
322
323
|
success: false,
|
|
@@ -364,7 +365,7 @@ MONITORING_ENABLED=true
|
|
|
364
365
|
|
|
365
366
|
private async clean(): Promise<void> {
|
|
366
367
|
// Clean output directory - implementation would go here
|
|
367
|
-
|
|
368
|
+
buildLogger.step("Cleaning output directory...")
|
|
368
369
|
}
|
|
369
370
|
|
|
370
371
|
private async generateManifest(
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { existsSync, readdirSync, writeFileSync, unlinkSync, readFileSync } from 'fs'
|
|
5
5
|
import { join, extname, basename } from 'path'
|
|
6
|
+
import { buildLogger } from '../utils/build-logger'
|
|
6
7
|
|
|
7
8
|
export interface ComponentInfo {
|
|
8
9
|
fileName: string
|
|
@@ -27,7 +28,6 @@ export class LiveComponentsGenerator {
|
|
|
27
28
|
*/
|
|
28
29
|
discoverComponents(): ComponentInfo[] {
|
|
29
30
|
if (!existsSync(this.componentsPath)) {
|
|
30
|
-
console.log('β οΈ Live components directory not found:', this.componentsPath)
|
|
31
31
|
return []
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -66,13 +66,13 @@ export class LiveComponentsGenerator {
|
|
|
66
66
|
componentName,
|
|
67
67
|
filePath: `./${fileName}`
|
|
68
68
|
})
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
|
|
70
|
+
buildLogger.step(`Discovered component: ${className} β ${componentName}`)
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
} catch (error) {
|
|
75
|
-
|
|
75
|
+
// Silently skip files that can't be analyzed
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -87,7 +87,6 @@ export class LiveComponentsGenerator {
|
|
|
87
87
|
if (existsSync(this.registrationFilePath)) {
|
|
88
88
|
const existingContent = readFileSync(this.registrationFilePath, 'utf-8')
|
|
89
89
|
writeFileSync(this.backupFilePath, existingContent)
|
|
90
|
-
console.log('π Backed up existing register-components.ts')
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
// Generate imports
|
|
@@ -130,7 +129,7 @@ ${components.map(comp => ` ${comp.className}`).join(',\n')}
|
|
|
130
129
|
`
|
|
131
130
|
|
|
132
131
|
writeFileSync(this.registrationFilePath, fileContent)
|
|
133
|
-
|
|
132
|
+
buildLogger.success(`Generated registration for ${components.length} components`)
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
/**
|
|
@@ -141,9 +140,6 @@ ${components.map(comp => ` ${comp.className}`).join(',\n')}
|
|
|
141
140
|
const backupContent = readFileSync(this.backupFilePath, 'utf-8')
|
|
142
141
|
writeFileSync(this.registrationFilePath, backupContent)
|
|
143
142
|
unlinkSync(this.backupFilePath)
|
|
144
|
-
console.log('π Restored original register-components.ts')
|
|
145
|
-
} else {
|
|
146
|
-
console.log('β οΈ No backup file found, keeping generated registration file')
|
|
147
143
|
}
|
|
148
144
|
}
|
|
149
145
|
|
|
@@ -163,17 +159,33 @@ ${components.map(comp => ` ${comp.className}`).join(',\n')}
|
|
|
163
159
|
* Pre-build hook: Generate registration file
|
|
164
160
|
*/
|
|
165
161
|
async preBuild(): Promise<ComponentInfo[]> {
|
|
166
|
-
|
|
167
|
-
|
|
162
|
+
buildLogger.section('Live Components Discovery', 'π')
|
|
163
|
+
|
|
168
164
|
const components = this.discoverComponents()
|
|
169
|
-
|
|
165
|
+
|
|
170
166
|
if (components.length === 0) {
|
|
171
|
-
|
|
167
|
+
buildLogger.warn('No Live Components found')
|
|
172
168
|
return []
|
|
173
169
|
}
|
|
174
170
|
|
|
171
|
+
// Create table of discovered components
|
|
172
|
+
const componentData = components.map(c => ({
|
|
173
|
+
component: c.componentName,
|
|
174
|
+
className: c.className,
|
|
175
|
+
file: c.fileName + '.ts'
|
|
176
|
+
}))
|
|
177
|
+
|
|
178
|
+
buildLogger.table(
|
|
179
|
+
[
|
|
180
|
+
{ header: 'Component', key: 'component', width: 20, align: 'left', color: 'cyan' },
|
|
181
|
+
{ header: 'Class Name', key: 'className', width: 25, align: 'left' },
|
|
182
|
+
{ header: 'File', key: 'file', width: 20, align: 'left', color: 'gray' }
|
|
183
|
+
],
|
|
184
|
+
componentData
|
|
185
|
+
)
|
|
186
|
+
|
|
175
187
|
this.generateRegistrationFile(components)
|
|
176
|
-
|
|
188
|
+
|
|
177
189
|
return components
|
|
178
190
|
}
|
|
179
191
|
|
|
@@ -181,10 +193,9 @@ ${components.map(comp => ` ${comp.className}`).join(',\n')}
|
|
|
181
193
|
* Post-build hook: Clean up generated file (optional)
|
|
182
194
|
*/
|
|
183
195
|
async postBuild(keepGenerated: boolean = false): Promise<void> {
|
|
184
|
-
|
|
185
|
-
|
|
196
|
+
buildLogger.step('Cleaning up Live Components registration...')
|
|
197
|
+
|
|
186
198
|
if (keepGenerated) {
|
|
187
|
-
console.log('π Keeping auto-generated registration file for production')
|
|
188
199
|
// Remove backup since we're keeping the generated version
|
|
189
200
|
if (existsSync(this.backupFilePath)) {
|
|
190
201
|
unlinkSync(this.backupFilePath)
|
|
@@ -220,7 +231,7 @@ ${components.map(comp => ` ${comp.className}`).join(',\n')}
|
|
|
220
231
|
*/
|
|
221
232
|
updateIfNeeded(): void {
|
|
222
233
|
if (this.needsUpdate()) {
|
|
223
|
-
|
|
234
|
+
buildLogger.info('Live Components changed, updating registration...')
|
|
224
235
|
const components = this.discoverComponents()
|
|
225
236
|
this.generateRegistrationFile(components)
|
|
226
237
|
}
|
package/core/build/optimizer.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync, writeFileSync, statSync, readdirSync } from "fs"
|
|
|
2
2
|
import { join, extname } from "path"
|
|
3
3
|
import { gzipSync } from "zlib"
|
|
4
4
|
import type { OptimizationConfig, OptimizationResult } from "../types/build"
|
|
5
|
+
import { buildLogger } from "../utils/build-logger"
|
|
5
6
|
|
|
6
7
|
export interface OptimizerConfig {
|
|
7
8
|
treeshake: boolean
|
|
@@ -19,8 +20,8 @@ export class Optimizer {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
async optimize(buildPath: string): Promise<OptimizationResult> {
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
buildLogger.section('Build Optimization', 'π§')
|
|
24
|
+
|
|
24
25
|
const startTime = Date.now()
|
|
25
26
|
const results: OptimizationResult = {
|
|
26
27
|
success: true,
|
|
@@ -34,6 +35,7 @@ export class Optimizer {
|
|
|
34
35
|
try {
|
|
35
36
|
// Get original size
|
|
36
37
|
results.originalSize = await this.calculateDirectorySize(buildPath)
|
|
38
|
+
buildLogger.step(`Original size: ${buildLogger.formatSize(results.originalSize)}`)
|
|
37
39
|
|
|
38
40
|
// Apply optimizations (minification removed for compatibility)
|
|
39
41
|
|
|
@@ -55,23 +57,40 @@ export class Optimizer {
|
|
|
55
57
|
|
|
56
58
|
// Calculate final size and compression ratio
|
|
57
59
|
results.optimizedSize = await this.calculateDirectorySize(buildPath)
|
|
58
|
-
results.compressionRatio = results.originalSize > 0
|
|
59
|
-
? ((results.originalSize - results.optimizedSize) / results.originalSize) * 100
|
|
60
|
+
results.compressionRatio = results.originalSize > 0
|
|
61
|
+
? ((results.originalSize - results.optimizedSize) / results.originalSize) * 100
|
|
60
62
|
: 0
|
|
61
63
|
|
|
62
64
|
results.duration = Date.now() - startTime
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
buildLogger.success(`Optimization completed in ${buildLogger.formatDuration(results.duration)}`)
|
|
67
|
+
|
|
68
|
+
// Create optimization summary table
|
|
69
|
+
const optimizationData = results.optimizations.map(opt => ({
|
|
70
|
+
type: opt.type,
|
|
71
|
+
description: opt.description,
|
|
72
|
+
saved: buildLogger.formatSize(opt.sizeSaved)
|
|
73
|
+
}))
|
|
74
|
+
|
|
75
|
+
if (optimizationData.length > 0) {
|
|
76
|
+
buildLogger.table(
|
|
77
|
+
[
|
|
78
|
+
{ header: 'Optimization', key: 'type', width: 20, align: 'left', color: 'cyan' },
|
|
79
|
+
{ header: 'Description', key: 'description', width: 35, align: 'left' },
|
|
80
|
+
{ header: 'Size Saved', key: 'saved', width: 12, align: 'right', color: 'green' }
|
|
81
|
+
],
|
|
82
|
+
optimizationData
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
67
86
|
return results
|
|
68
87
|
|
|
69
88
|
} catch (error) {
|
|
70
89
|
results.success = false
|
|
71
90
|
results.duration = Date.now() - startTime
|
|
72
91
|
results.error = error instanceof Error ? error.message : "Unknown optimization error"
|
|
73
|
-
|
|
74
|
-
|
|
92
|
+
|
|
93
|
+
buildLogger.error(`Optimization failed: ${results.error}`)
|
|
75
94
|
return results
|
|
76
95
|
}
|
|
77
96
|
}
|
|
@@ -79,8 +98,8 @@ export class Optimizer {
|
|
|
79
98
|
// Minification methods removed for compatibility with Bun bundler
|
|
80
99
|
|
|
81
100
|
private async compressAssets(buildPath: string, results: OptimizationResult): Promise<void> {
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
buildLogger.step("Compressing assets...")
|
|
102
|
+
|
|
84
103
|
const files = this.getFilesRecursively(buildPath)
|
|
85
104
|
let compressedCount = 0
|
|
86
105
|
|
|
@@ -98,11 +117,12 @@ export class Optimizer {
|
|
|
98
117
|
compressedCount++
|
|
99
118
|
}
|
|
100
119
|
} catch (error) {
|
|
101
|
-
|
|
120
|
+
// Silently skip files that can't be compressed
|
|
102
121
|
}
|
|
103
122
|
}
|
|
104
123
|
}
|
|
105
124
|
|
|
125
|
+
buildLogger.success(`Compressed ${compressedCount} files`)
|
|
106
126
|
results.optimizations.push({
|
|
107
127
|
type: 'compression',
|
|
108
128
|
description: `Created gzip versions for ${compressedCount} files`,
|
|
@@ -111,8 +131,8 @@ export class Optimizer {
|
|
|
111
131
|
}
|
|
112
132
|
|
|
113
133
|
private async removeUnusedCSS(buildPath: string, results: OptimizationResult): Promise<void> {
|
|
114
|
-
|
|
115
|
-
|
|
134
|
+
buildLogger.step("Analyzing CSS...")
|
|
135
|
+
|
|
116
136
|
// This is a placeholder - real implementation would use PurgeCSS or similar
|
|
117
137
|
results.optimizations.push({
|
|
118
138
|
type: 'css-purging',
|
|
@@ -122,8 +142,8 @@ export class Optimizer {
|
|
|
122
142
|
}
|
|
123
143
|
|
|
124
144
|
private async optimizeImages(buildPath: string, results: OptimizationResult): Promise<void> {
|
|
125
|
-
|
|
126
|
-
|
|
145
|
+
buildLogger.step("Optimizing images...")
|
|
146
|
+
|
|
127
147
|
// This is a placeholder - real implementation would use imagemin or similar
|
|
128
148
|
results.optimizations.push({
|
|
129
149
|
type: 'image-optimization',
|
|
@@ -133,7 +153,7 @@ export class Optimizer {
|
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
private async analyzeBundles(buildPath: string, results: OptimizationResult): Promise<void> {
|
|
136
|
-
|
|
156
|
+
buildLogger.step("Analyzing bundles...")
|
|
137
157
|
|
|
138
158
|
const files = this.getFilesRecursively(buildPath)
|
|
139
159
|
const jsFiles = files.filter(f => extname(f) === '.js')
|
package/core/cli/index.ts
CHANGED
|
@@ -452,14 +452,18 @@ async function handleLegacyCommands() {
|
|
|
452
452
|
console.log("π API Server: http://localhost:3001")
|
|
453
453
|
console.log("π¦ Starting backend with hot reload...")
|
|
454
454
|
console.log()
|
|
455
|
-
|
|
455
|
+
|
|
456
|
+
// Ensure backend-only.ts exists
|
|
457
|
+
const { ensureBackendEntry } = await import("../utils/regenerate-files")
|
|
458
|
+
await ensureBackendEntry()
|
|
459
|
+
|
|
456
460
|
// Start backend with Bun watch for hot reload
|
|
457
461
|
const { spawn: spawnBackend } = await import("child_process")
|
|
458
462
|
const backendProcess = spawnBackend("bun", ["--watch", "app/server/backend-only.ts"], {
|
|
459
463
|
stdio: "inherit",
|
|
460
464
|
cwd: process.cwd()
|
|
461
465
|
})
|
|
462
|
-
|
|
466
|
+
|
|
463
467
|
// Handle process cleanup
|
|
464
468
|
process.on('SIGINT', () => {
|
|
465
469
|
backendProcess.kill('SIGINT')
|
package/core/config/env.ts
CHANGED
|
@@ -417,6 +417,8 @@ export function getEnvironmentRecommendations(environment: string): Partial<Flux
|
|
|
417
417
|
target: 'bun' as const,
|
|
418
418
|
outDir: 'dist',
|
|
419
419
|
clean: true,
|
|
420
|
+
minify: false,
|
|
421
|
+
treeshake: false,
|
|
420
422
|
optimization: {
|
|
421
423
|
minify: false,
|
|
422
424
|
compress: false,
|
|
@@ -459,6 +461,8 @@ export function getEnvironmentRecommendations(environment: string): Partial<Flux
|
|
|
459
461
|
target: 'bun' as const,
|
|
460
462
|
outDir: 'dist',
|
|
461
463
|
clean: true,
|
|
464
|
+
minify: true,
|
|
465
|
+
treeshake: true,
|
|
462
466
|
optimization: {
|
|
463
467
|
minify: true,
|
|
464
468
|
compress: true,
|
|
@@ -7,7 +7,9 @@ import { env, createNamespace } from '../utils/env'
|
|
|
7
7
|
import type { FluxStackConfig } from './schema'
|
|
8
8
|
import { defaultFluxStackConfig } from './schema'
|
|
9
9
|
import { loggerConfig } from '../../config/logger.config'
|
|
10
|
-
import {
|
|
10
|
+
import { clientConfig } from '../../config/client.config'
|
|
11
|
+
import { serverConfig } from '../../config/server.config'
|
|
12
|
+
import { monitoringConfig } from '../../config/monitoring.config'
|
|
11
13
|
import { appConfig } from '../../config/app.config'
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -163,7 +165,7 @@ export const runtimeConfig = {
|
|
|
163
165
|
.override('logging.format', 'json')
|
|
164
166
|
.override('build.optimization.minify', true)
|
|
165
167
|
.override('build.sourceMaps', false)
|
|
166
|
-
.override('monitoring.enabled',
|
|
168
|
+
.override('monitoring.enabled', monitoringConfig.monitoring.enabled)
|
|
167
169
|
.build()
|
|
168
170
|
},
|
|
169
171
|
|
|
@@ -304,14 +306,14 @@ export const configHelpers = {
|
|
|
304
306
|
return {
|
|
305
307
|
port: env.VITE_PORT,
|
|
306
308
|
proxy: {
|
|
307
|
-
target:
|
|
308
|
-
changeOrigin:
|
|
309
|
+
target: clientConfig.proxy.target,
|
|
310
|
+
changeOrigin: clientConfig.proxy.changeOrigin
|
|
309
311
|
},
|
|
310
312
|
build: {
|
|
311
|
-
outDir:
|
|
312
|
-
sourceMaps:
|
|
313
|
-
minify:
|
|
314
|
-
target:
|
|
313
|
+
outDir: clientConfig.build.outDir,
|
|
314
|
+
sourceMaps: clientConfig.build.sourceMaps,
|
|
315
|
+
minify: clientConfig.build.minify,
|
|
316
|
+
target: clientConfig.build.target
|
|
315
317
|
}
|
|
316
318
|
}
|
|
317
319
|
}
|
package/core/config/schema.ts
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Enhanced Configuration Schema for FluxStack
|
|
3
|
-
*
|
|
2
|
+
* β οΈ DEPRECATED - Enhanced Configuration Schema for FluxStack
|
|
3
|
+
*
|
|
4
|
+
* This file is DEPRECATED and maintained only for backward compatibility.
|
|
5
|
+
* Please use the new modular config system from /config instead:
|
|
6
|
+
*
|
|
7
|
+
* β
NEW WAY:
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { appConfig, serverConfig, clientConfig } from '@/config'
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* β OLD WAY (DEPRECATED):
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { FluxStackConfig } from '@/core/config/schema'
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* The modular system provides:
|
|
18
|
+
* - Better organization (separated by domain)
|
|
19
|
+
* - Automatic validation
|
|
20
|
+
* - Type inference
|
|
21
|
+
* - Laravel-style declarative schemas
|
|
22
|
+
*
|
|
23
|
+
* This file will be removed in a future version.
|
|
24
|
+
* @deprecated Use /config modular system instead
|
|
4
25
|
*/
|
|
5
26
|
|
|
27
|
+
|
|
6
28
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error'
|
|
7
29
|
export type BuildTarget = 'bun' | 'node' | 'docker'
|
|
8
30
|
export type LogFormat = 'json' | 'pretty'
|
package/core/framework/server.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { logger } from "../utils/logger"
|
|
|
8
8
|
import { displayStartupBanner, type StartupInfo } from "../utils/logger/startup-banner"
|
|
9
9
|
import { createErrorHandler } from "../utils/errors/handlers"
|
|
10
10
|
import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
|
|
11
|
+
import type { Plugin } from "../plugins"
|
|
11
12
|
|
|
12
13
|
export class FluxStackFramework {
|
|
13
14
|
private app: Elysia
|
package/core/index.ts
CHANGED
|
@@ -3,26 +3,34 @@
|
|
|
3
3
|
* Main exports for the FluxStack framework
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
//
|
|
11
|
-
export * from './
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export * from './
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export * from './
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
export {
|
|
6
|
+
// Framework core (primary exports)
|
|
7
|
+
export { FluxStackFramework } from './framework/server'
|
|
8
|
+
export { FluxStackClient } from './framework/client'
|
|
9
|
+
|
|
10
|
+
// Server components (includes config types via re-export)
|
|
11
|
+
export * from './server'
|
|
12
|
+
|
|
13
|
+
// Client components
|
|
14
|
+
export * from './client'
|
|
15
|
+
|
|
16
|
+
// Testing utilities
|
|
17
|
+
export * from './testing'
|
|
18
|
+
|
|
19
|
+
// Build system
|
|
20
|
+
export * from './build'
|
|
21
|
+
|
|
22
|
+
// CLI and generators
|
|
23
|
+
export * from './cli/generators'
|
|
24
|
+
|
|
25
|
+
// Plugin system (avoid wildcard to prevent conflicts)
|
|
26
|
+
export { PluginRegistry } from './plugins/registry'
|
|
27
|
+
export { PluginDiscovery, pluginDiscovery } from './plugins/discovery'
|
|
28
|
+
export { PluginManager } from './plugins/manager'
|
|
29
|
+
export { PluginUtils } from './plugins'
|
|
30
|
+
|
|
31
|
+
// Utilities
|
|
32
|
+
export * from './utils/logger'
|
|
33
|
+
// Note: errors are already exported via ./server (BuildError), avoid duplicate export
|
|
34
|
+
|
|
35
|
+
// Version
|
|
36
|
+
export { FLUXSTACK_VERSION } from './utils/version'
|