create-fluxstack 1.1.0 ā 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/server/backend-only.ts +5 -5
- package/app/server/index.ts +63 -54
- package/app/server/live/FluxStackConfig.ts +43 -39
- package/app/server/live/SystemMonitorIntegration.ts +2 -2
- package/app/server/live/register-components.ts +1 -1
- package/app/server/middleware/errorHandling.ts +6 -4
- package/app/server/routes/config.ts +145 -0
- package/app/server/routes/index.ts +5 -3
- package/config/app.config.ts +113 -0
- package/config/build.config.ts +24 -0
- package/config/database.config.ts +99 -0
- package/config/index.ts +68 -0
- package/config/logger.config.ts +27 -0
- package/config/runtime.config.ts +92 -0
- package/config/server.config.ts +46 -0
- package/config/services.config.ts +130 -0
- package/config/system.config.ts +105 -0
- package/core/build/index.ts +10 -4
- package/core/cli/generators/index.ts +5 -2
- package/core/cli/generators/plugin.ts +290 -0
- package/core/cli/index.ts +117 -15
- package/core/config/env.ts +37 -95
- package/core/config/runtime-config.ts +61 -58
- package/core/config/schema.ts +4 -0
- package/core/framework/server.ts +22 -10
- package/core/plugins/built-in/index.ts +7 -17
- package/core/plugins/built-in/swagger/index.ts +228 -228
- package/core/plugins/built-in/vite/index.ts +374 -358
- package/core/plugins/dependency-manager.ts +5 -5
- package/core/plugins/manager.ts +12 -12
- package/core/plugins/registry.ts +3 -3
- package/core/server/index.ts +0 -1
- package/core/server/live/ComponentRegistry.ts +34 -8
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/websocket-plugin.ts +434 -434
- package/core/server/middleware/README.md +488 -0
- package/core/server/middleware/elysia-helpers.ts +227 -0
- package/core/server/middleware/index.ts +25 -9
- package/core/server/plugins/static-files-plugin.ts +231 -231
- package/core/utils/config-schema.ts +484 -0
- package/core/utils/env.ts +306 -0
- package/core/utils/helpers.ts +4 -4
- package/core/utils/logger/colors.ts +114 -0
- package/core/utils/logger/config.ts +35 -0
- package/core/utils/logger/formatter.ts +82 -0
- package/core/utils/logger/group-logger.ts +101 -0
- package/core/utils/logger/index.ts +199 -250
- package/core/utils/logger/stack-trace.ts +92 -0
- package/core/utils/logger/startup-banner.ts +92 -0
- package/core/utils/logger/winston-logger.ts +152 -0
- package/core/utils/version.ts +5 -0
- package/create-fluxstack.ts +118 -8
- package/fluxstack.config.ts +2 -2
- package/package.json +117 -115
- package/core/config/env-dynamic.ts +0 -326
- package/core/plugins/built-in/logger/index.ts +0 -180
- package/core/server/plugins/logger.ts +0 -47
- package/core/utils/env-runtime-v2.ts +0 -232
- package/core/utils/env-runtime.ts +0 -259
- package/core/utils/logger/formatters.ts +0 -222
- package/core/utils/logger/middleware.ts +0 -253
- package/core/utils/logger/performance.ts +0 -384
- package/core/utils/logger/transports.ts +0 -365
- package/core/utils/logger.ts +0 -106
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import type { Generator } from "./index.js"
|
|
2
|
+
import type { GeneratorContext, GeneratorOptions, Template } from "./types.js"
|
|
3
|
+
import { templateEngine } from "./template-engine.js"
|
|
4
|
+
import { join } from "path"
|
|
5
|
+
|
|
6
|
+
export class PluginGenerator implements Generator {
|
|
7
|
+
name = 'plugin'
|
|
8
|
+
description = 'Generate a new FluxStack plugin'
|
|
9
|
+
|
|
10
|
+
async generate(context: GeneratorContext, options: GeneratorOptions): Promise<void> {
|
|
11
|
+
const template = this.getTemplate(options.template)
|
|
12
|
+
|
|
13
|
+
if (template.hooks?.beforeGenerate) {
|
|
14
|
+
await template.hooks.beforeGenerate(context, options)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const files = await templateEngine.processTemplate(template, context, options)
|
|
18
|
+
|
|
19
|
+
if (options.dryRun) {
|
|
20
|
+
console.log(`\nš Would generate plugin '${options.name}':\n`)
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
console.log(`${file.action === 'create' ? 'š' : 'āļø'} ${file.path}`)
|
|
23
|
+
}
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await templateEngine.generateFiles(files, options.dryRun)
|
|
28
|
+
|
|
29
|
+
if (template.hooks?.afterGenerate) {
|
|
30
|
+
const filePaths = files.map(f => f.path)
|
|
31
|
+
await template.hooks.afterGenerate(context, options, filePaths)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(`\nā
Generated plugin '${options.name}' with ${files.length} files`)
|
|
35
|
+
console.log(`\nš¦ Next steps:`)
|
|
36
|
+
console.log(` 1. Edit plugins/${options.name}/plugin.json with your plugin metadata`)
|
|
37
|
+
console.log(` 2. Implement your plugin logic in plugins/${options.name}/index.ts`)
|
|
38
|
+
console.log(` 3. Add server-side code in plugins/${options.name}/server/ (optional)`)
|
|
39
|
+
console.log(` 4. Add client-side code in plugins/${options.name}/client/ (optional)`)
|
|
40
|
+
console.log(` 5. Run: bun run cli plugin:deps install`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private getTemplate(templateName?: string): Template {
|
|
44
|
+
switch (templateName) {
|
|
45
|
+
case 'full':
|
|
46
|
+
return this.getFullTemplate()
|
|
47
|
+
case 'server':
|
|
48
|
+
return this.getServerOnlyTemplate()
|
|
49
|
+
case 'client':
|
|
50
|
+
return this.getClientOnlyTemplate()
|
|
51
|
+
default:
|
|
52
|
+
return this.getBasicTemplate()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private getBasicTemplate(): Template {
|
|
57
|
+
return {
|
|
58
|
+
name: 'basic-plugin',
|
|
59
|
+
description: 'Basic plugin template with essential files',
|
|
60
|
+
files: [
|
|
61
|
+
{
|
|
62
|
+
path: 'plugins/{{name}}/plugin.json',
|
|
63
|
+
content: `{
|
|
64
|
+
"name": "{{name}}",
|
|
65
|
+
"version": "1.0.0",
|
|
66
|
+
"description": "{{description}}",
|
|
67
|
+
"author": "Your Name",
|
|
68
|
+
"type": "fluxstack-plugin",
|
|
69
|
+
"main": "index.ts",
|
|
70
|
+
"dependencies": {},
|
|
71
|
+
"fluxstack": {
|
|
72
|
+
"minVersion": "1.4.0"
|
|
73
|
+
},
|
|
74
|
+
"hooks": {
|
|
75
|
+
"setup": true,
|
|
76
|
+
"onServerStart": false,
|
|
77
|
+
"onRequest": false,
|
|
78
|
+
"onResponse": false,
|
|
79
|
+
"onError": false
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
`
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
path: 'plugins/{{name}}/index.ts',
|
|
86
|
+
content: `import type { FluxStackPlugin, PluginContext } from '@/core/types/plugin'
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* {{pascalName}} Plugin
|
|
90
|
+
* {{description}}
|
|
91
|
+
*/
|
|
92
|
+
export class {{pascalName}}Plugin implements FluxStackPlugin {
|
|
93
|
+
name = '{{name}}'
|
|
94
|
+
version = '1.0.0'
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Setup hook - called when plugin is loaded
|
|
98
|
+
*/
|
|
99
|
+
async setup(context: PluginContext): Promise<void> {
|
|
100
|
+
console.log(\`[{{name}}] Plugin initialized\`)
|
|
101
|
+
|
|
102
|
+
// Add your initialization logic here
|
|
103
|
+
// Example: Register middleware, setup database connections, etc.
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Server start hook - called when server starts
|
|
108
|
+
*/
|
|
109
|
+
async onServerStart?(context: PluginContext): Promise<void> {
|
|
110
|
+
console.log(\`[{{name}}] Server started\`)
|
|
111
|
+
|
|
112
|
+
// Add logic to run when server starts
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Request hook - called on each request
|
|
117
|
+
*/
|
|
118
|
+
async onRequest?(context: PluginContext, request: Request): Promise<void> {
|
|
119
|
+
// Add request processing logic
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Response hook - called on each response
|
|
124
|
+
*/
|
|
125
|
+
async onResponse?(context: PluginContext, response: Response): Promise<void> {
|
|
126
|
+
// Add response processing logic
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Error hook - called when errors occur
|
|
131
|
+
*/
|
|
132
|
+
async onError?(context: PluginContext, error: Error): Promise<void> {
|
|
133
|
+
console.error(\`[{{name}}] Error:\`, error)
|
|
134
|
+
|
|
135
|
+
// Add error handling logic
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Export plugin instance
|
|
140
|
+
export default new {{pascalName}}Plugin()
|
|
141
|
+
`
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
path: 'plugins/{{name}}/README.md',
|
|
145
|
+
content: `# {{pascalName}} Plugin
|
|
146
|
+
|
|
147
|
+
{{description}}
|
|
148
|
+
|
|
149
|
+
## Installation
|
|
150
|
+
|
|
151
|
+
This plugin is already in your FluxStack project. To use it:
|
|
152
|
+
|
|
153
|
+
1. Make sure the plugin is enabled in your configuration
|
|
154
|
+
2. Install any additional dependencies (if needed):
|
|
155
|
+
\`\`\`bash
|
|
156
|
+
bun run cli plugin:deps install
|
|
157
|
+
\`\`\`
|
|
158
|
+
|
|
159
|
+
## Usage
|
|
160
|
+
|
|
161
|
+
\`\`\`typescript
|
|
162
|
+
// The plugin is automatically loaded by FluxStack
|
|
163
|
+
// Configure it in your app/server/index.ts if needed
|
|
164
|
+
\`\`\`
|
|
165
|
+
|
|
166
|
+
## Configuration
|
|
167
|
+
|
|
168
|
+
Add configuration options here.
|
|
169
|
+
|
|
170
|
+
## API
|
|
171
|
+
|
|
172
|
+
Document your plugin's API here.
|
|
173
|
+
|
|
174
|
+
## Hooks
|
|
175
|
+
|
|
176
|
+
This plugin uses the following hooks:
|
|
177
|
+
- \`setup\`: Initialize plugin resources
|
|
178
|
+
- \`onServerStart\`: Run when server starts (optional)
|
|
179
|
+
- \`onRequest\`: Process incoming requests (optional)
|
|
180
|
+
- \`onResponse\`: Process outgoing responses (optional)
|
|
181
|
+
- \`onError\`: Handle errors (optional)
|
|
182
|
+
|
|
183
|
+
## Development
|
|
184
|
+
|
|
185
|
+
To modify this plugin:
|
|
186
|
+
|
|
187
|
+
1. Edit \`index.ts\` with your logic
|
|
188
|
+
2. Update \`plugin.json\` with metadata
|
|
189
|
+
3. Test with: \`bun run dev\`
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|
|
194
|
+
`
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private getServerOnlyTemplate(): Template {
|
|
201
|
+
const basic = this.getBasicTemplate()
|
|
202
|
+
return {
|
|
203
|
+
...basic,
|
|
204
|
+
name: 'server-plugin',
|
|
205
|
+
description: 'Plugin with server-side code',
|
|
206
|
+
files: [
|
|
207
|
+
...basic.files,
|
|
208
|
+
{
|
|
209
|
+
path: 'plugins/{{name}}/server/index.ts',
|
|
210
|
+
content: `/**
|
|
211
|
+
* Server-side logic for {{pascalName}} plugin
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
export class {{pascalName}}Service {
|
|
215
|
+
async initialize() {
|
|
216
|
+
console.log(\`[{{name}}] Server service initialized\`)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Add your server-side methods here
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export const {{camelName}}Service = new {{pascalName}}Service()
|
|
223
|
+
`
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private getClientOnlyTemplate(): Template {
|
|
230
|
+
const basic = this.getBasicTemplate()
|
|
231
|
+
return {
|
|
232
|
+
...basic,
|
|
233
|
+
name: 'client-plugin',
|
|
234
|
+
description: 'Plugin with client-side code',
|
|
235
|
+
files: [
|
|
236
|
+
...basic.files,
|
|
237
|
+
{
|
|
238
|
+
path: 'plugins/{{name}}/client/index.ts',
|
|
239
|
+
content: `/**
|
|
240
|
+
* Client-side logic for {{pascalName}} plugin
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
export class {{pascalName}}Client {
|
|
244
|
+
initialize() {
|
|
245
|
+
console.log(\`[{{name}}] Client initialized\`)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Add your client-side methods here
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export const {{camelName}}Client = new {{pascalName}}Client()
|
|
252
|
+
`
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private getFullTemplate(): Template {
|
|
259
|
+
const basic = this.getBasicTemplate()
|
|
260
|
+
const server = this.getServerOnlyTemplate()
|
|
261
|
+
const client = this.getClientOnlyTemplate()
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
...basic,
|
|
265
|
+
name: 'full-plugin',
|
|
266
|
+
description: 'Complete plugin with server and client code',
|
|
267
|
+
files: [
|
|
268
|
+
...basic.files,
|
|
269
|
+
...server.files.slice(basic.files.length), // Add server files
|
|
270
|
+
...client.files.slice(basic.files.length), // Add client files
|
|
271
|
+
{
|
|
272
|
+
path: 'plugins/{{name}}/types.ts',
|
|
273
|
+
content: `/**
|
|
274
|
+
* Type definitions for {{pascalName}} plugin
|
|
275
|
+
*/
|
|
276
|
+
|
|
277
|
+
export interface {{pascalName}}Config {
|
|
278
|
+
// Add your configuration types here
|
|
279
|
+
enabled: boolean
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface {{pascalName}}Options {
|
|
283
|
+
// Add your options types here
|
|
284
|
+
}
|
|
285
|
+
`
|
|
286
|
+
}
|
|
287
|
+
]
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
package/core/cli/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { getConfigSync } from "../config"
|
|
|
6
6
|
import { cliRegistry } from "./command-registry"
|
|
7
7
|
import { pluginDiscovery } from "./plugin-discovery"
|
|
8
8
|
import { generateCommand, interactiveGenerateCommand } from "./generators/index.js"
|
|
9
|
+
import { startGroup, endGroup, logBox, logInGroup } from "../utils/logger/group-logger"
|
|
9
10
|
|
|
10
11
|
const command = process.argv[2]
|
|
11
12
|
const args = process.argv.slice(3)
|
|
@@ -134,12 +135,20 @@ Examples:
|
|
|
134
135
|
}
|
|
135
136
|
],
|
|
136
137
|
handler: async (args, options, context) => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
// Grouped startup messages
|
|
139
|
+
startGroup({
|
|
140
|
+
title: 'FluxStack Development Server',
|
|
141
|
+
icon: 'ā”',
|
|
142
|
+
color: 'cyan'
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
logInGroup(`Frontend: http://localhost:${options['frontend-port']}`, 'š')
|
|
146
|
+
logInGroup(`Backend: http://localhost:${options.port}`, 'š')
|
|
147
|
+
logInGroup('Backend inicia Vite programaticamente', 'š')
|
|
148
|
+
logInGroup('Starting backend server...', 'š¦')
|
|
149
|
+
|
|
150
|
+
endGroup()
|
|
151
|
+
console.log('') // Separator line
|
|
143
152
|
|
|
144
153
|
const { spawn } = await import("child_process")
|
|
145
154
|
const devProcess = spawn("bun", ["--watch", "app/server/index.ts"], {
|
|
@@ -215,7 +224,7 @@ Examples:
|
|
|
215
224
|
}
|
|
216
225
|
})
|
|
217
226
|
|
|
218
|
-
// Create command
|
|
227
|
+
// Create command
|
|
219
228
|
cliRegistry.register({
|
|
220
229
|
name: 'create',
|
|
221
230
|
description: 'Create a new FluxStack project',
|
|
@@ -243,7 +252,7 @@ Examples:
|
|
|
243
252
|
],
|
|
244
253
|
handler: async (args, options, context) => {
|
|
245
254
|
const [projectName, template] = args
|
|
246
|
-
|
|
255
|
+
|
|
247
256
|
if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
|
|
248
257
|
console.error("ā Project name can only contain letters, numbers, hyphens, and underscores")
|
|
249
258
|
return
|
|
@@ -254,7 +263,7 @@ Examples:
|
|
|
254
263
|
name: projectName,
|
|
255
264
|
template: template as 'basic' | 'full' || 'basic'
|
|
256
265
|
})
|
|
257
|
-
|
|
266
|
+
|
|
258
267
|
await creator.create()
|
|
259
268
|
} catch (error) {
|
|
260
269
|
console.error("ā Failed to create project:", error instanceof Error ? error.message : String(error))
|
|
@@ -262,6 +271,91 @@ Examples:
|
|
|
262
271
|
}
|
|
263
272
|
}
|
|
264
273
|
})
|
|
274
|
+
|
|
275
|
+
// Make:plugin command (shortcut for generate plugin)
|
|
276
|
+
cliRegistry.register({
|
|
277
|
+
name: 'make:plugin',
|
|
278
|
+
description: 'Create a new FluxStack plugin',
|
|
279
|
+
category: 'Plugins',
|
|
280
|
+
usage: 'flux make:plugin <name> [options]',
|
|
281
|
+
aliases: ['create:plugin'],
|
|
282
|
+
examples: [
|
|
283
|
+
'flux make:plugin my-plugin # Create basic plugin',
|
|
284
|
+
'flux make:plugin my-plugin --template full # Create full plugin with server/client',
|
|
285
|
+
'flux make:plugin auth --template server # Create server-only plugin'
|
|
286
|
+
],
|
|
287
|
+
arguments: [
|
|
288
|
+
{
|
|
289
|
+
name: 'name',
|
|
290
|
+
description: 'Name of the plugin to create',
|
|
291
|
+
required: true,
|
|
292
|
+
type: 'string'
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
options: [
|
|
296
|
+
{
|
|
297
|
+
name: 'template',
|
|
298
|
+
short: 't',
|
|
299
|
+
description: 'Plugin template to use',
|
|
300
|
+
type: 'string',
|
|
301
|
+
choices: ['basic', 'full', 'server', 'client'],
|
|
302
|
+
default: 'basic'
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: 'description',
|
|
306
|
+
short: 'd',
|
|
307
|
+
description: 'Plugin description',
|
|
308
|
+
type: 'string',
|
|
309
|
+
default: 'A FluxStack plugin'
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: 'force',
|
|
313
|
+
short: 'f',
|
|
314
|
+
description: 'Overwrite existing plugin',
|
|
315
|
+
type: 'boolean',
|
|
316
|
+
default: false
|
|
317
|
+
}
|
|
318
|
+
],
|
|
319
|
+
handler: async (args, options, context) => {
|
|
320
|
+
const [name] = args
|
|
321
|
+
|
|
322
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(name)) {
|
|
323
|
+
console.error("ā Plugin name can only contain letters, numbers, hyphens, and underscores")
|
|
324
|
+
return
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Use the plugin generator
|
|
328
|
+
const { generatorRegistry } = await import('./generators/index.js')
|
|
329
|
+
const pluginGenerator = generatorRegistry.get('plugin')
|
|
330
|
+
|
|
331
|
+
if (!pluginGenerator) {
|
|
332
|
+
console.error("ā Plugin generator not found")
|
|
333
|
+
return
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const generatorContext = {
|
|
337
|
+
workingDir: context.workingDir,
|
|
338
|
+
config: context.config,
|
|
339
|
+
logger: context.logger,
|
|
340
|
+
utils: context.utils
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const generatorOptions = {
|
|
344
|
+
name,
|
|
345
|
+
template: options.template,
|
|
346
|
+
force: options.force,
|
|
347
|
+
dryRun: false,
|
|
348
|
+
description: options.description
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
try {
|
|
352
|
+
await pluginGenerator.generate(generatorContext, generatorOptions)
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.error("ā Failed to create plugin:", error instanceof Error ? error.message : String(error))
|
|
355
|
+
throw error
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
})
|
|
265
359
|
}
|
|
266
360
|
|
|
267
361
|
// Main CLI logic
|
|
@@ -293,12 +387,20 @@ async function main() {
|
|
|
293
387
|
async function handleLegacyCommands() {
|
|
294
388
|
switch (command) {
|
|
295
389
|
case "dev":
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
390
|
+
// Grouped startup messages
|
|
391
|
+
startGroup({
|
|
392
|
+
title: 'FluxStack Development Server',
|
|
393
|
+
icon: 'ā”',
|
|
394
|
+
color: 'cyan'
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
logInGroup('Frontend: http://localhost:5173', 'š')
|
|
398
|
+
logInGroup('Backend: http://localhost:3000', 'š')
|
|
399
|
+
logInGroup('Backend inicia Vite programaticamente', 'š')
|
|
400
|
+
logInGroup('Starting backend server...', 'š¦')
|
|
401
|
+
|
|
402
|
+
endGroup()
|
|
403
|
+
console.log('') // Separator line
|
|
302
404
|
|
|
303
405
|
// Start only backend - it will start Vite programmatically
|
|
304
406
|
const { spawn } = await import("child_process")
|
package/core/config/env.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Handles environment variable processing and precedence
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { env, helpers } from '../utils/env'
|
|
6
7
|
import type { FluxStackConfig, LogLevel, BuildTarget, LogFormat } from './schema'
|
|
7
8
|
|
|
8
9
|
export interface EnvironmentInfo {
|
|
@@ -24,8 +25,6 @@ export interface ConfigPrecedence {
|
|
|
24
25
|
* Get current environment information
|
|
25
26
|
*/
|
|
26
27
|
export function getEnvironmentInfo(): EnvironmentInfo {
|
|
27
|
-
// Import here to avoid circular dependency
|
|
28
|
-
const { env } = require('../utils/env-runtime-v2')
|
|
29
28
|
const nodeEnv = env.NODE_ENV
|
|
30
29
|
|
|
31
30
|
return {
|
|
@@ -99,117 +98,60 @@ export class EnvironmentProcessor {
|
|
|
99
98
|
const config: any = {}
|
|
100
99
|
|
|
101
100
|
// App configuration
|
|
102
|
-
this.setConfigValue(config, 'app.name',
|
|
103
|
-
|
|
104
|
-
this.setConfigValue(config, 'app.version',
|
|
105
|
-
process.env.FLUXSTACK_APP_VERSION || process.env.APP_VERSION, 'string')
|
|
106
|
-
this.setConfigValue(config, 'app.description',
|
|
107
|
-
process.env.FLUXSTACK_APP_DESCRIPTION || process.env.APP_DESCRIPTION, 'string')
|
|
101
|
+
this.setConfigValue(config, 'app.name', env.FLUXSTACK_APP_NAME, 'string')
|
|
102
|
+
this.setConfigValue(config, 'app.version', env.FLUXSTACK_APP_VERSION, 'string')
|
|
108
103
|
|
|
109
104
|
// Server configuration
|
|
110
|
-
this.setConfigValue(config, 'server.port',
|
|
111
|
-
|
|
112
|
-
this.setConfigValue(config, 'server.
|
|
113
|
-
process.env.HOST || process.env.FLUXSTACK_HOST, 'string')
|
|
114
|
-
this.setConfigValue(config, 'server.apiPrefix',
|
|
115
|
-
process.env.FLUXSTACK_API_PREFIX || process.env.API_PREFIX, 'string')
|
|
105
|
+
this.setConfigValue(config, 'server.port', env.PORT?.toString(), 'number')
|
|
106
|
+
this.setConfigValue(config, 'server.host', env.HOST, 'string')
|
|
107
|
+
this.setConfigValue(config, 'server.apiPrefix', env.API_PREFIX, 'string')
|
|
116
108
|
|
|
117
109
|
// CORS configuration
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this.setConfigValue(config, 'server.cors.
|
|
123
|
-
|
|
124
|
-
this.setConfigValue(config, 'server.cors.
|
|
125
|
-
|
|
126
|
-
this.setConfigValue(config, 'server.cors.maxAge',
|
|
127
|
-
process.env.CORS_MAX_AGE || process.env.FLUXSTACK_CORS_MAX_AGE, 'number')
|
|
110
|
+
const corsOriginsStr = env.has('CORS_ORIGINS') ? env.all().CORS_ORIGINS : undefined
|
|
111
|
+
const corsMethodsStr = env.has('CORS_METHODS') ? env.all().CORS_METHODS : undefined
|
|
112
|
+
const corsHeadersStr = env.has('CORS_HEADERS') ? env.all().CORS_HEADERS : undefined
|
|
113
|
+
|
|
114
|
+
this.setConfigValue(config, 'server.cors.origins', corsOriginsStr, 'array')
|
|
115
|
+
this.setConfigValue(config, 'server.cors.methods', corsMethodsStr, 'array')
|
|
116
|
+
this.setConfigValue(config, 'server.cors.headers', corsHeadersStr, 'array')
|
|
117
|
+
this.setConfigValue(config, 'server.cors.credentials', env.CORS_CREDENTIALS?.toString(), 'boolean')
|
|
118
|
+
this.setConfigValue(config, 'server.cors.maxAge', env.CORS_MAX_AGE?.toString(), 'number')
|
|
128
119
|
|
|
129
120
|
// Client configuration
|
|
130
|
-
this.setConfigValue(config, 'client.port',
|
|
131
|
-
process.env.VITE_PORT || process.env.CLIENT_PORT || process.env.FLUXSTACK_CLIENT_PORT, 'number')
|
|
132
|
-
this.setConfigValue(config, 'client.proxy.target',
|
|
133
|
-
process.env.VITE_API_URL || process.env.API_URL || process.env.FLUXSTACK_PROXY_TARGET, 'string')
|
|
134
|
-
this.setConfigValue(config, 'client.build.sourceMaps',
|
|
135
|
-
process.env.FLUXSTACK_CLIENT_SOURCEMAPS, 'boolean')
|
|
136
|
-
this.setConfigValue(config, 'client.build.minify',
|
|
137
|
-
process.env.FLUXSTACK_CLIENT_MINIFY, 'boolean')
|
|
121
|
+
this.setConfigValue(config, 'client.port', env.VITE_PORT?.toString(), 'number')
|
|
138
122
|
|
|
139
123
|
// Build configuration
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
this.setConfigValue(config, 'build.outDir',
|
|
143
|
-
process.env.BUILD_OUTDIR || process.env.FLUXSTACK_BUILD_OUTDIR, 'string')
|
|
144
|
-
this.setConfigValue(config, 'build.sourceMaps',
|
|
145
|
-
process.env.BUILD_SOURCEMAPS || process.env.FLUXSTACK_BUILD_SOURCEMAPS, 'boolean')
|
|
146
|
-
this.setConfigValue(config, 'build.clean',
|
|
147
|
-
process.env.BUILD_CLEAN || process.env.FLUXSTACK_BUILD_CLEAN, 'boolean')
|
|
148
|
-
|
|
149
|
-
// Build optimization
|
|
150
|
-
this.setConfigValue(config, 'build.optimization.minify',
|
|
151
|
-
process.env.BUILD_MINIFY || process.env.FLUXSTACK_BUILD_MINIFY, 'boolean')
|
|
152
|
-
this.setConfigValue(config, 'build.optimization.treeshake',
|
|
153
|
-
process.env.BUILD_TREESHAKE || process.env.FLUXSTACK_BUILD_TREESHAKE, 'boolean')
|
|
154
|
-
this.setConfigValue(config, 'build.optimization.compress',
|
|
155
|
-
process.env.BUILD_COMPRESS || process.env.FLUXSTACK_BUILD_COMPRESS, 'boolean')
|
|
156
|
-
this.setConfigValue(config, 'build.optimization.splitChunks',
|
|
157
|
-
process.env.BUILD_SPLIT_CHUNKS || process.env.FLUXSTACK_BUILD_SPLIT_CHUNKS, 'boolean')
|
|
158
|
-
this.setConfigValue(config, 'build.optimization.bundleAnalyzer',
|
|
159
|
-
process.env.BUILD_ANALYZER || process.env.FLUXSTACK_BUILD_ANALYZER, 'boolean')
|
|
124
|
+
const buildMinify = env.has('BUILD_MINIFY') ? env.all().BUILD_MINIFY : undefined
|
|
125
|
+
this.setConfigValue(config, 'build.optimization.minify', buildMinify, 'boolean')
|
|
160
126
|
|
|
161
127
|
// Logging configuration
|
|
162
|
-
this.setConfigValue(config, 'logging.level',
|
|
163
|
-
|
|
164
|
-
this.setConfigValue(config, 'logging.format',
|
|
165
|
-
process.env.LOG_FORMAT || process.env.FLUXSTACK_LOG_FORMAT, 'logFormat')
|
|
128
|
+
this.setConfigValue(config, 'logging.level', env.LOG_LEVEL, 'logLevel')
|
|
129
|
+
this.setConfigValue(config, 'logging.format', env.LOG_FORMAT, 'logFormat')
|
|
166
130
|
|
|
167
131
|
// Monitoring configuration
|
|
168
|
-
this.setConfigValue(config, 'monitoring.enabled',
|
|
169
|
-
|
|
170
|
-
this.setConfigValue(config, 'monitoring.metrics.enabled',
|
|
171
|
-
process.env.METRICS_ENABLED || process.env.FLUXSTACK_METRICS_ENABLED, 'boolean')
|
|
172
|
-
this.setConfigValue(config, 'monitoring.metrics.collectInterval',
|
|
173
|
-
process.env.METRICS_INTERVAL || process.env.FLUXSTACK_METRICS_INTERVAL, 'number')
|
|
174
|
-
this.setConfigValue(config, 'monitoring.profiling.enabled',
|
|
175
|
-
process.env.PROFILING_ENABLED || process.env.FLUXSTACK_PROFILING_ENABLED, 'boolean')
|
|
176
|
-
this.setConfigValue(config, 'monitoring.profiling.sampleRate',
|
|
177
|
-
process.env.PROFILING_SAMPLE_RATE || process.env.FLUXSTACK_PROFILING_SAMPLE_RATE, 'number')
|
|
132
|
+
this.setConfigValue(config, 'monitoring.enabled', env.ENABLE_MONITORING?.toString(), 'boolean')
|
|
133
|
+
this.setConfigValue(config, 'monitoring.metrics.enabled', env.ENABLE_METRICS?.toString(), 'boolean')
|
|
178
134
|
|
|
179
135
|
// Database configuration
|
|
180
|
-
this.setConfigValue(config, 'database.url',
|
|
181
|
-
this.setConfigValue(config, 'database.host',
|
|
182
|
-
this.setConfigValue(config, 'database.port',
|
|
183
|
-
this.setConfigValue(config, 'database.database',
|
|
184
|
-
this.setConfigValue(config, 'database.user',
|
|
185
|
-
this.setConfigValue(config, 'database.password',
|
|
186
|
-
this.setConfigValue(config, 'database.ssl',
|
|
187
|
-
this.setConfigValue(config, 'database.poolSize', process.env.DATABASE_POOL_SIZE, 'number')
|
|
136
|
+
this.setConfigValue(config, 'database.url', env.DATABASE_URL, 'string')
|
|
137
|
+
this.setConfigValue(config, 'database.host', env.DB_HOST, 'string')
|
|
138
|
+
this.setConfigValue(config, 'database.port', env.DB_PORT?.toString(), 'number')
|
|
139
|
+
this.setConfigValue(config, 'database.database', env.DB_NAME, 'string')
|
|
140
|
+
this.setConfigValue(config, 'database.user', env.DB_USER, 'string')
|
|
141
|
+
this.setConfigValue(config, 'database.password', env.DB_PASSWORD, 'string')
|
|
142
|
+
this.setConfigValue(config, 'database.ssl', env.DB_SSL?.toString(), 'boolean')
|
|
188
143
|
|
|
189
144
|
// Auth configuration
|
|
190
|
-
this.setConfigValue(config, 'auth.secret',
|
|
191
|
-
this.setConfigValue(config, 'auth.expiresIn',
|
|
192
|
-
this.setConfigValue(config, 'auth.algorithm',
|
|
193
|
-
this.setConfigValue(config, 'auth.issuer', process.env.JWT_ISSUER, 'string')
|
|
145
|
+
this.setConfigValue(config, 'auth.secret', env.JWT_SECRET, 'string')
|
|
146
|
+
this.setConfigValue(config, 'auth.expiresIn', env.JWT_EXPIRES_IN, 'string')
|
|
147
|
+
this.setConfigValue(config, 'auth.algorithm', env.JWT_ALGORITHM, 'string')
|
|
194
148
|
|
|
195
149
|
// Email configuration
|
|
196
|
-
this.setConfigValue(config, 'email.host',
|
|
197
|
-
this.setConfigValue(config, 'email.port',
|
|
198
|
-
this.setConfigValue(config, 'email.user',
|
|
199
|
-
this.setConfigValue(config, 'email.password',
|
|
200
|
-
this.setConfigValue(config, 'email.secure',
|
|
201
|
-
this.setConfigValue(config, 'email.from', process.env.SMTP_FROM, 'string')
|
|
202
|
-
|
|
203
|
-
// Storage configuration
|
|
204
|
-
this.setConfigValue(config, 'storage.uploadPath', process.env.UPLOAD_PATH, 'string')
|
|
205
|
-
this.setConfigValue(config, 'storage.maxFileSize', process.env.MAX_FILE_SIZE, 'number')
|
|
206
|
-
this.setConfigValue(config, 'storage.provider', process.env.STORAGE_PROVIDER, 'string')
|
|
207
|
-
|
|
208
|
-
// Plugin configuration
|
|
209
|
-
this.setConfigValue(config, 'plugins.enabled',
|
|
210
|
-
process.env.FLUXSTACK_PLUGINS_ENABLED, 'array')
|
|
211
|
-
this.setConfigValue(config, 'plugins.disabled',
|
|
212
|
-
process.env.FLUXSTACK_PLUGINS_DISABLED, 'array')
|
|
150
|
+
this.setConfigValue(config, 'email.host', env.SMTP_HOST, 'string')
|
|
151
|
+
this.setConfigValue(config, 'email.port', env.SMTP_PORT?.toString(), 'number')
|
|
152
|
+
this.setConfigValue(config, 'email.user', env.SMTP_USER, 'string')
|
|
153
|
+
this.setConfigValue(config, 'email.password', env.SMTP_PASSWORD, 'string')
|
|
154
|
+
this.setConfigValue(config, 'email.secure', env.SMTP_SECURE?.toString(), 'boolean')
|
|
213
155
|
|
|
214
156
|
return this.cleanEmptyObjects(config)
|
|
215
157
|
}
|