create-fluxstack 1.4.0 → 1.5.0

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 (55) hide show
  1. package/.env.example +8 -1
  2. package/CRYPTO-AUTH-MIDDLEWARE-GUIDE.md +475 -0
  3. package/CRYPTO-AUTH-MIDDLEWARES.md +473 -0
  4. package/CRYPTO-AUTH-USAGE.md +491 -0
  5. package/EXEMPLO-ROTA-PROTEGIDA.md +347 -0
  6. package/QUICK-START-CRYPTO-AUTH.md +221 -0
  7. package/app/client/src/App.tsx +4 -1
  8. package/app/client/src/pages/CryptoAuthPage.tsx +394 -0
  9. package/app/server/index.ts +4 -0
  10. package/app/server/routes/crypto-auth-demo.routes.ts +167 -0
  11. package/app/server/routes/example-with-crypto-auth.routes.ts +235 -0
  12. package/app/server/routes/exemplo-posts.routes.ts +161 -0
  13. package/app/server/routes/index.ts +5 -1
  14. package/config/index.ts +9 -1
  15. package/core/cli/generators/index.ts +5 -2
  16. package/core/cli/generators/plugin.ts +580 -0
  17. package/core/cli/generators/template-engine.ts +5 -0
  18. package/core/cli/index.ts +88 -3
  19. package/core/cli/plugin-discovery.ts +33 -12
  20. package/core/framework/server.ts +10 -0
  21. package/core/plugins/dependency-manager.ts +89 -22
  22. package/core/plugins/index.ts +4 -0
  23. package/core/plugins/manager.ts +3 -2
  24. package/core/plugins/module-resolver.ts +216 -0
  25. package/core/plugins/registry.ts +28 -1
  26. package/core/utils/logger/index.ts +4 -0
  27. package/core/utils/version.ts +1 -1
  28. package/create-fluxstack.ts +117 -8
  29. package/fluxstack.config.ts +253 -114
  30. package/package.json +117 -117
  31. package/plugins/crypto-auth/README.md +722 -172
  32. package/plugins/crypto-auth/ai-context.md +1282 -0
  33. package/plugins/crypto-auth/cli/make-protected-route.command.ts +383 -0
  34. package/plugins/crypto-auth/client/CryptoAuthClient.ts +136 -159
  35. package/plugins/crypto-auth/client/components/AuthProvider.tsx +35 -94
  36. package/plugins/crypto-auth/client/components/LoginButton.tsx +36 -53
  37. package/plugins/crypto-auth/client/components/ProtectedRoute.tsx +17 -37
  38. package/plugins/crypto-auth/client/components/index.ts +1 -4
  39. package/plugins/crypto-auth/client/index.ts +1 -1
  40. package/plugins/crypto-auth/config/index.ts +34 -0
  41. package/plugins/crypto-auth/index.ts +84 -152
  42. package/plugins/crypto-auth/package.json +65 -64
  43. package/plugins/crypto-auth/server/AuthMiddleware.ts +19 -75
  44. package/plugins/crypto-auth/server/CryptoAuthService.ts +60 -167
  45. package/plugins/crypto-auth/server/index.ts +15 -2
  46. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +65 -0
  47. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +26 -0
  48. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +76 -0
  49. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +45 -0
  50. package/plugins/crypto-auth/server/middlewares/helpers.ts +140 -0
  51. package/plugins/crypto-auth/server/middlewares/index.ts +22 -0
  52. package/plugins/crypto-auth/server/middlewares.ts +19 -0
  53. package/test-crypto-auth.ts +101 -0
  54. package/plugins/crypto-auth/client/components/SessionInfo.tsx +0 -242
  55. package/plugins/crypto-auth/plugin.json +0 -29
@@ -5,16 +5,17 @@ import { resolve, join } from 'path'
5
5
  import { existsSync, mkdirSync, cpSync, writeFileSync, readFileSync } from 'fs'
6
6
  import chalk from 'chalk'
7
7
  import ora from 'ora'
8
+ import { FLUXSTACK_VERSION } from './core/utils/version'
8
9
 
9
10
  const logo = `
10
- ⚡ ███████ ██ ██ ██ ██ ██ ███████ ████████ █████ ██████ ██ ██
11
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
12
- █████ ██ ██ ██ ███ ███████ ██ ███████ ██ █████
13
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
14
- ██ ███████ ██████ ██ ██ ███████ ██ ██ ██ ██████ ██ ██
11
+ ⚡ ███████ ██ ██ ██ ██ ██ ███████ ████████ █████ ██████ ██ ██
12
+ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
13
+ █████ ██ ██ ██ ███ ███████ ██ ███████ ██ █████
14
+ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
15
+ ██ ███████ ██████ ██ ██ ███████ ██ ██ ██ ██████ ██ ██
15
16
 
16
17
  ${chalk.cyan('💫 Powered by Bun - The Divine Runtime ⚡')}
17
- ${chalk.gray('Creates FluxStack apps by copying the working framework')}
18
+ ${chalk.gray(`FluxStack v${FLUXSTACK_VERSION} - Creates full-stack TypeScript apps`)}
18
19
  `
19
20
 
20
21
  program
@@ -58,6 +59,7 @@ program
58
59
  'core',
59
60
  'app',
60
61
  'config', // ✅ CRITICAL: Copy config folder with declarative configs
62
+ // 'plugins', // TODO: Copy when crypto-auth plugin is complete
61
63
  'ai-context', // ✅ CRITICAL: Copy AI documentation for users
62
64
  'bun.lock', // ✅ CRITICAL: Copy lockfile to maintain working versions
63
65
  'package.json', // ✅ Copy real package.json from framework
@@ -67,15 +69,122 @@ program
67
69
  'CLAUDE.md', // ✅ Project instructions for AI assistants
68
70
  'README.md'
69
71
  ]
70
-
72
+
71
73
  for (const file of filesToCopy) {
72
74
  const sourcePath = join(frameworkDir, file)
73
75
  const destPath = join(projectPath, file)
74
-
76
+
75
77
  if (existsSync(sourcePath)) {
76
78
  cpSync(sourcePath, destPath, { recursive: true })
77
79
  }
78
80
  }
81
+
82
+ // Create empty plugins directory for user plugins
83
+ const pluginsDir = join(projectPath, 'plugins')
84
+ mkdirSync(pluginsDir, { recursive: true })
85
+
86
+ // Create a README in plugins folder
87
+ const pluginsReadme = `# Plugins
88
+
89
+ This folder is for your custom FluxStack plugins.
90
+
91
+ ## 📖 Documentation
92
+
93
+ For complete plugin development guide, see:
94
+ - \`ai-context/development/plugins-guide.md\` - Full plugin documentation
95
+ - \`ai-context/examples/\` - Plugin examples
96
+
97
+ ## 📦 Available CLI Commands
98
+
99
+ \`\`\`bash
100
+ # Create a new plugin
101
+ bun run cli make:plugin my-plugin # Basic plugin
102
+ bun run cli make:plugin my-plugin --template full # Full plugin (server + client)
103
+ bun run cli make:plugin my-plugin --template server # Server-only plugin
104
+
105
+ # Manage plugin dependencies
106
+ bun run cli plugin:deps install # Install plugin dependencies
107
+ bun run cli plugin:deps list # List plugin dependencies
108
+ bun run cli plugin:deps check # Check for conflicts
109
+ bun run cli plugin:deps clean # Clean unused dependencies
110
+ \`\`\`
111
+
112
+ ## 🔌 Plugin Structure
113
+
114
+ \`\`\`
115
+ plugins/
116
+ ├── my-plugin/
117
+ │ ├── plugin.json # Plugin metadata (name, version, dependencies)
118
+ │ ├── index.ts # Plugin entry point (server-side hooks)
119
+ │ ├── server/ # Server-side code (optional)
120
+ │ └── client/ # Client-side code (optional)
121
+ \`\`\`
122
+
123
+ ## ⚡ Quick Start
124
+
125
+ 1. Create your plugin folder: \`plugins/my-plugin/\`
126
+ 2. Create \`plugin.json\` with metadata
127
+ 3. Create \`index.ts\` with your plugin logic
128
+ 4. Use \`bun run cli plugin:deps install\` if you need extra dependencies
129
+
130
+ ## 🔌 Intercepting Requests
131
+
132
+ Plugins can intercept and modify requests using hooks:
133
+
134
+ \`\`\`typescript
135
+ // plugins/my-plugin/index.ts
136
+ import type { FluxStackPlugin, PluginContext } from '@/core/types/plugin'
137
+
138
+ export class MyPlugin implements FluxStackPlugin {
139
+ name = 'my-plugin'
140
+ version = '1.0.0'
141
+
142
+ // Intercept every request
143
+ async onRequest(context: PluginContext, request: Request): Promise<void> {
144
+ // Example: Add custom headers
145
+ const url = new URL(request.url)
146
+ console.log(\`[\${this.name}] Request to: \${url.pathname}\`)
147
+
148
+ // Example: Validate authentication
149
+ const token = request.headers.get('Authorization')
150
+ if (!token && url.pathname.startsWith('/api/protected')) {
151
+ throw new Error('Unauthorized')
152
+ }
153
+ }
154
+
155
+ // Intercept every response
156
+ async onResponse(context: PluginContext, response: Response): Promise<void> {
157
+ console.log(\`[\${this.name}] Response status: \${response.status}\`)
158
+ }
159
+
160
+ // Handle errors
161
+ async onError(context: PluginContext, error: Error): Promise<void> {
162
+ console.error(\`[\${this.name}] Error:\`, error.message)
163
+ // Example: Send to error tracking service
164
+ }
165
+ }
166
+ \`\`\`
167
+
168
+ ## 📋 Available Hooks
169
+
170
+ - **\`setup\`**: Initialize plugin resources (called once at startup)
171
+ - **\`onServerStart\`**: Run when server starts
172
+ - **\`onRequest\`**: Intercept incoming requests (before route handlers)
173
+ - **\`onResponse\`**: Intercept outgoing responses (after route handlers)
174
+ - **\`onError\`**: Handle errors globally
175
+
176
+ ## 💡 Common Use Cases
177
+
178
+ - **Authentication**: Validate tokens in \`onRequest\`
179
+ - **Logging**: Log requests/responses for analytics
180
+ - **Rate Limiting**: Track request counts per IP
181
+ - **CORS**: Add headers in \`onResponse\`
182
+ - **Request Transformation**: Modify request body/headers
183
+ - **Response Transformation**: Add custom headers, compress responses
184
+
185
+ See the documentation for detailed examples and best practices.
186
+ `
187
+ writeFileSync(join(pluginsDir, 'README.md'), pluginsReadme)
79
188
 
80
189
  // Generate .gitignore using template (instead of copying)
81
190
  const gitignoreContent = `# Dependencies
@@ -1,74 +1,261 @@
1
1
  /**
2
2
  * FluxStack Configuration
3
- * Enhanced configuration with comprehensive settings and environment support
4
- * Uses unified environment loader
3
+ * Using declarative config system with schema validation and type inference
4
+ * Laravel-inspired declarative configuration with full type safety
5
5
  */
6
6
 
7
7
  import type { FluxStackConfig } from './core/config/schema'
8
+ import { defineConfig, config as configHelpers } from './core/utils/config-schema'
8
9
  import { env, helpers } from './core/utils/env'
9
10
 
10
11
  console.log(`🔧 Loading FluxStack config for ${env.NODE_ENV} environment`)
11
12
 
12
- // Main FluxStack configuration with dynamic env vars
13
+ // ============================================================================
14
+ // 📋 DECLARATIVE CONFIG SCHEMAS
15
+ // ============================================================================
16
+
17
+ /**
18
+ * Application Configuration Schema
19
+ */
20
+ const appConfigSchema = {
21
+ name: configHelpers.string('FLUXSTACK_APP_NAME', 'FluxStack', true),
22
+ version: configHelpers.string('FLUXSTACK_APP_VERSION', '1.0.0', true),
23
+ description: configHelpers.string('FLUXSTACK_APP_DESCRIPTION', 'A FluxStack application')
24
+ } as const
25
+
26
+ /**
27
+ * CORS Configuration Schema
28
+ */
29
+ const corsConfigSchema = {
30
+ origins: configHelpers.array('CORS_ORIGINS', ['http://localhost:3000', 'http://localhost:5173']),
31
+ methods: configHelpers.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
32
+ headers: configHelpers.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
33
+ credentials: configHelpers.boolean('CORS_CREDENTIALS', false),
34
+ maxAge: configHelpers.number('CORS_MAX_AGE', 86400)
35
+ } as const
36
+
37
+ /**
38
+ * Server Configuration Schema
39
+ */
40
+ const serverConfigSchema = {
41
+ port: configHelpers.number('PORT', 3000, true),
42
+ host: configHelpers.string('HOST', 'localhost', true),
43
+ apiPrefix: configHelpers.string('API_PREFIX', '/api', true)
44
+ } as const
45
+
46
+ /**
47
+ * Client Proxy Configuration Schema
48
+ */
49
+ const clientProxyConfigSchema = {
50
+ target: {
51
+ type: 'string' as const,
52
+ env: 'PROXY_TARGET',
53
+ default: helpers.getServerUrl(),
54
+ required: false
55
+ },
56
+ changeOrigin: configHelpers.boolean('PROXY_CHANGE_ORIGIN', true)
57
+ } as const
58
+
59
+ /**
60
+ * Client Build Configuration Schema
61
+ */
62
+ const clientBuildConfigSchema = {
63
+ sourceMaps: configHelpers.boolean('CLIENT_SOURCEMAPS', helpers.isDevelopment()),
64
+ minify: configHelpers.boolean('CLIENT_MINIFY', helpers.isProduction()),
65
+ target: configHelpers.string('CLIENT_TARGET', 'esnext'),
66
+ outDir: configHelpers.string('CLIENT_OUTDIR', 'dist/client')
67
+ } as const
68
+
69
+ /**
70
+ * Client Configuration Schema
71
+ */
72
+ const clientConfigSchema = {
73
+ port: configHelpers.number('VITE_PORT', 5173, true)
74
+ } as const
75
+
76
+ /**
77
+ * Build Optimization Configuration Schema
78
+ */
79
+ const buildOptimizationConfigSchema = {
80
+ minify: configHelpers.boolean('BUILD_MINIFY', helpers.isProduction()),
81
+ treeshake: configHelpers.boolean('BUILD_TREESHAKE', helpers.isProduction()),
82
+ compress: configHelpers.boolean('BUILD_COMPRESS', helpers.isProduction()),
83
+ splitChunks: configHelpers.boolean('BUILD_SPLIT_CHUNKS', true),
84
+ bundleAnalyzer: configHelpers.boolean('BUILD_ANALYZER', helpers.isDevelopment())
85
+ } as const
86
+
87
+ /**
88
+ * Build Configuration Schema
89
+ */
90
+ const buildConfigSchema = {
91
+ target: configHelpers.enum('BUILD_TARGET', ['bun', 'node', 'docker'] as const, 'bun'),
92
+ outDir: configHelpers.string('BUILD_OUTDIR', 'dist'),
93
+ sourceMaps: configHelpers.boolean('BUILD_SOURCEMAPS', !helpers.isProduction()),
94
+ minify: configHelpers.boolean('BUILD_MINIFY', helpers.isProduction()),
95
+ treeshake: configHelpers.boolean('BUILD_TREESHAKE', helpers.isProduction()),
96
+ clean: configHelpers.boolean('BUILD_CLEAN', true)
97
+ } as const
98
+
99
+ /**
100
+ * Plugins Configuration Schema
101
+ */
102
+ const pluginsConfigSchema = {
103
+ enabled: configHelpers.array('FLUXSTACK_PLUGINS_ENABLED', ['logger', 'swagger', 'vite', 'cors', 'static-files', 'crypto-auth']),
104
+ disabled: configHelpers.array('FLUXSTACK_PLUGINS_DISABLED', [])
105
+ } as const
106
+
107
+ /**
108
+ * Logging Configuration Schema
109
+ */
110
+ const loggingConfigSchema = {
111
+ level: configHelpers.enum('LOG_LEVEL', ['debug', 'info', 'warn', 'error'] as const, helpers.isDevelopment() ? 'debug' : 'info'),
112
+ format: configHelpers.enum('LOG_FORMAT', ['json', 'pretty'] as const, helpers.isDevelopment() ? 'pretty' : 'json')
113
+ } as const
114
+
115
+ /**
116
+ * Monitoring Metrics Configuration Schema
117
+ */
118
+ const monitoringMetricsConfigSchema = {
119
+ enabled: configHelpers.boolean('ENABLE_METRICS', false),
120
+ collectInterval: configHelpers.number('METRICS_INTERVAL', 5000),
121
+ httpMetrics: configHelpers.boolean('HTTP_METRICS', true),
122
+ systemMetrics: configHelpers.boolean('SYSTEM_METRICS', true),
123
+ customMetrics: configHelpers.boolean('CUSTOM_METRICS', false)
124
+ } as const
125
+
126
+ /**
127
+ * Monitoring Profiling Configuration Schema
128
+ */
129
+ const monitoringProfilingConfigSchema = {
130
+ enabled: configHelpers.boolean('PROFILING_ENABLED', false),
131
+ sampleRate: configHelpers.number('PROFILING_SAMPLE_RATE', 0.1),
132
+ memoryProfiling: configHelpers.boolean('MEMORY_PROFILING', false),
133
+ cpuProfiling: configHelpers.boolean('CPU_PROFILING', false)
134
+ } as const
135
+
136
+ /**
137
+ * Monitoring Configuration Schema
138
+ */
139
+ const monitoringConfigSchema = {
140
+ enabled: configHelpers.boolean('ENABLE_MONITORING', false),
141
+ exporters: configHelpers.array('MONITORING_EXPORTERS', [])
142
+ } as const
143
+
144
+ /**
145
+ * Database Configuration Schema (Optional)
146
+ */
147
+ const databaseConfigSchema = {
148
+ url: configHelpers.string('DATABASE_URL', ''),
149
+ host: configHelpers.string('DB_HOST', ''),
150
+ port: configHelpers.number('DB_PORT', 5432),
151
+ database: configHelpers.string('DB_NAME', ''),
152
+ user: configHelpers.string('DB_USER', ''),
153
+ password: configHelpers.string('DB_PASSWORD', ''),
154
+ ssl: configHelpers.boolean('DB_SSL', false),
155
+ poolSize: configHelpers.number('DB_POOL_SIZE', 10)
156
+ } as const
157
+
158
+ /**
159
+ * Auth Configuration Schema (Optional)
160
+ */
161
+ const authConfigSchema = {
162
+ secret: configHelpers.string('JWT_SECRET', ''),
163
+ expiresIn: configHelpers.string('JWT_EXPIRES_IN', '24h'),
164
+ algorithm: configHelpers.string('JWT_ALGORITHM', 'HS256'),
165
+ issuer: configHelpers.string('JWT_ISSUER', '')
166
+ } as const
167
+
168
+ /**
169
+ * Email Configuration Schema (Optional)
170
+ */
171
+ const emailConfigSchema = {
172
+ host: configHelpers.string('SMTP_HOST', ''),
173
+ port: configHelpers.number('SMTP_PORT', 587),
174
+ user: configHelpers.string('SMTP_USER', ''),
175
+ password: configHelpers.string('SMTP_PASSWORD', ''),
176
+ secure: configHelpers.boolean('SMTP_SECURE', false),
177
+ from: configHelpers.string('SMTP_FROM', '')
178
+ } as const
179
+
180
+ /**
181
+ * Storage Configuration Schema (Optional)
182
+ */
183
+ const storageConfigSchema = {
184
+ uploadPath: configHelpers.string('UPLOAD_PATH', ''),
185
+ maxFileSize: configHelpers.number('MAX_FILE_SIZE', 10485760), // 10MB
186
+ allowedTypes: configHelpers.array('ALLOWED_FILE_TYPES', []),
187
+ provider: configHelpers.enum('STORAGE_PROVIDER', ['local', 's3', 'gcs'] as const, 'local')
188
+ } as const
189
+
190
+ // ============================================================================
191
+ // ⚡ LOAD CONFIGURATIONS USING DECLARATIVE SYSTEM
192
+ // ============================================================================
193
+
194
+ const appConfig = defineConfig(appConfigSchema)
195
+ const corsConfig = defineConfig(corsConfigSchema)
196
+ const serverConfig = defineConfig(serverConfigSchema)
197
+ const clientProxyConfig = defineConfig(clientProxyConfigSchema)
198
+ const clientBuildConfig = defineConfig(clientBuildConfigSchema)
199
+ const clientConfig = defineConfig(clientConfigSchema)
200
+ const buildOptimizationConfig = defineConfig(buildOptimizationConfigSchema)
201
+ const buildConfig = defineConfig(buildConfigSchema)
202
+ const pluginsConfig = defineConfig(pluginsConfigSchema)
203
+ const loggingConfig = defineConfig(loggingConfigSchema)
204
+ const monitoringMetricsConfig = defineConfig(monitoringMetricsConfigSchema)
205
+ const monitoringProfilingConfig = defineConfig(monitoringProfilingConfigSchema)
206
+ const monitoringConfig = defineConfig(monitoringConfigSchema)
207
+
208
+ // Optional configs (only load if env vars are present)
209
+ const databaseConfig = (env.has('DATABASE_URL') || env.has('DATABASE_HOST'))
210
+ ? defineConfig(databaseConfigSchema)
211
+ : undefined
212
+
213
+ const authConfig = env.has('JWT_SECRET')
214
+ ? defineConfig(authConfigSchema)
215
+ : undefined
216
+
217
+ const emailConfig = env.has('SMTP_HOST')
218
+ ? defineConfig(emailConfigSchema)
219
+ : undefined
220
+
221
+ const storageConfig = (env.has('UPLOAD_PATH') || env.has('STORAGE_PROVIDER'))
222
+ ? defineConfig(storageConfigSchema)
223
+ : undefined
224
+
225
+ // ============================================================================
226
+ // 🚀 MAIN FLUXSTACK CONFIGURATION
227
+ // ============================================================================
228
+
13
229
  export const config: FluxStackConfig = {
14
230
  // Application metadata
15
- app: {
16
- name: env.FLUXSTACK_APP_NAME, // Direto! (string)
17
- version: env.FLUXSTACK_APP_VERSION, // Direto! (string)
18
- description: env.get('FLUXSTACK_APP_DESCRIPTION', 'A FluxStack application')
19
- },
231
+ app: appConfig,
20
232
 
21
233
  // Server configuration
22
234
  server: {
23
- port: env.PORT, // Direto! (number)
24
- host: env.HOST, // Direto! (string)
25
- apiPrefix: env.API_PREFIX, // Direto! (string)
26
- cors: {
27
- origins: env.CORS_ORIGINS, // Direto! (string[])
28
- methods: env.get('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
29
- headers: env.get('CORS_HEADERS', ['Content-Type', 'Authorization']),
30
- credentials: env.get('CORS_CREDENTIALS', false), // boolean casting
31
- maxAge: env.get('CORS_MAX_AGE', 86400) // number casting
32
- },
235
+ ...serverConfig,
236
+ cors: corsConfig,
33
237
  middleware: []
34
238
  },
35
239
 
36
240
  // Client configuration
37
241
  client: {
38
- port: env.VITE_PORT, // Direto! (number)
39
- proxy: {
40
- target: helpers.getServerUrl(), // Helper inteligente
41
- changeOrigin: env.get('PROXY_CHANGE_ORIGIN', true)
42
- },
43
- build: {
44
- sourceMaps: env.get('CLIENT_SOURCEMAPS', helpers.isDevelopment()),
45
- target: env.get('CLIENT_TARGET', 'esnext'),
46
- outDir: env.get('CLIENT_OUTDIR', 'dist/client')
47
- }
242
+ ...clientConfig,
243
+ proxy: clientProxyConfig,
244
+ build: clientBuildConfig
48
245
  },
49
246
 
50
247
  // Build configuration
51
248
  build: {
52
- target: env.get('BUILD_TARGET', 'bun'), // string casting
53
- outDir: env.get('BUILD_OUTDIR', 'dist'), // string
54
- optimization: {
55
- treeshake: env.get('BUILD_TREESHAKE', helpers.isProduction()),
56
- compress: env.get('BUILD_COMPRESS', helpers.isProduction()),
57
- splitChunks: env.get('BUILD_SPLIT_CHUNKS', true),
58
- bundleAnalyzer: env.get('BUILD_ANALYZER', helpers.isDevelopment())
59
- },
60
- sourceMaps: env.get('BUILD_SOURCEMAPS', !helpers.isProduction()),
61
- clean: env.get('BUILD_CLEAN', true)
249
+ ...buildConfig,
250
+ optimization: buildOptimizationConfig
62
251
  },
63
252
 
64
253
  // Plugin configuration
65
254
  plugins: {
66
- enabled: env.get('FLUXSTACK_PLUGINS_ENABLED', ['logger', 'swagger', 'vite', 'cors', 'static-files', 'crypto-auth']),
67
- disabled: env.get('FLUXSTACK_PLUGINS_DISABLED', []),
255
+ ...pluginsConfig,
68
256
  config: {
69
- // Plugin-specific configurations can be added here
70
257
  logger: {
71
- // Logger plugin config will be handled by logging section
258
+ // Logger plugin config handled by logging section
72
259
  },
73
260
  swagger: {
74
261
  title: env.get('SWAGGER_TITLE', 'FluxStack API'),
@@ -81,95 +268,39 @@ export const config: FluxStackConfig = {
81
268
  cacheMaxAge: env.get('STATIC_CACHE_MAX_AGE', 31536000), // 1 year
82
269
  enableUploads: env.get('STATIC_ENABLE_UPLOADS', true),
83
270
  enablePublic: env.get('STATIC_ENABLE_PUBLIC', true)
84
- },
85
- 'crypto-auth': {
86
- enabled: env.get('CRYPTO_AUTH_ENABLED', true),
87
- sessionTimeout: env.get('CRYPTO_AUTH_SESSION_TIMEOUT', 1800000), // 30 minutos
88
- maxTimeDrift: env.get('CRYPTO_AUTH_MAX_TIME_DRIFT', 300000), // 5 minutos
89
- adminKeys: env.get('CRYPTO_AUTH_ADMIN_KEYS', []),
90
- protectedRoutes: env.get('CRYPTO_AUTH_PROTECTED_ROUTES', ['/api/admin/*', '/api/protected/*']),
91
- publicRoutes: env.get('CRYPTO_AUTH_PUBLIC_ROUTES', ['/api/auth/*', '/api/health', '/api/docs']),
92
- enableMetrics: env.get('CRYPTO_AUTH_ENABLE_METRICS', true)
93
271
  }
272
+ // ✅ crypto-auth manages its own configuration
273
+ // See: plugins/crypto-auth/config/index.ts
94
274
  }
95
275
  },
96
276
 
97
277
  // Logging configuration
98
278
  logging: {
99
- level: env.LOG_LEVEL as any, // Direto! (com smart default)
100
- format: env.get('LOG_FORMAT', helpers.isDevelopment() ? 'pretty' : 'json'),
279
+ ...loggingConfig,
101
280
  transports: [
102
281
  {
103
282
  type: 'console' as const,
104
- level: env.LOG_LEVEL as any, // Direto! (com smart default)
105
- format: env.get('LOG_FORMAT', helpers.isDevelopment() ? 'pretty' : 'json')
283
+ level: loggingConfig.level,
284
+ format: loggingConfig.format
106
285
  }
107
286
  ]
108
287
  },
109
288
 
110
289
  // Monitoring configuration
111
290
  monitoring: {
112
- enabled: env.ENABLE_MONITORING, // Direto! (boolean)
113
- metrics: {
114
- enabled: env.ENABLE_METRICS, // Direto! (boolean)
115
- collectInterval: env.get('METRICS_INTERVAL', 5000), // number casting
116
- httpMetrics: env.get('HTTP_METRICS', true),
117
- systemMetrics: env.get('SYSTEM_METRICS', true),
118
- customMetrics: env.get('CUSTOM_METRICS', false)
119
- },
120
- profiling: {
121
- enabled: env.get('PROFILING_ENABLED', false),
122
- sampleRate: env.get('PROFILING_SAMPLE_RATE', 0.1), // number casting
123
- memoryProfiling: env.get('MEMORY_PROFILING', false),
124
- cpuProfiling: env.get('CPU_PROFILING', false)
125
- },
126
- exporters: env.get('MONITORING_EXPORTERS', []) // array casting
291
+ ...monitoringConfig,
292
+ metrics: monitoringMetricsConfig,
293
+ profiling: monitoringProfilingConfig
127
294
  },
128
295
 
129
- // Optional database configuration
130
- ...(env.has('DATABASE_URL') || env.has('DATABASE_HOST') ? {
131
- database: {
132
- url: env.DATABASE_URL, // Direto! (string)
133
- host: env.DB_HOST, // Direto! (string)
134
- port: env.DB_PORT, // Direto! (number)
135
- database: env.DB_NAME, // Direto! (string)
136
- user: env.DB_USER, // Direto! (string)
137
- password: env.DB_PASSWORD, // Direto! (string)
138
- ssl: env.DB_SSL, // Direto! (boolean)
139
- poolSize: env.get('DB_POOL_SIZE', 10) // number casting
140
- }
141
- } : {}),
142
-
143
- // Optional authentication configuration
144
- ...(env.has('JWT_SECRET') ? {
145
- auth: {
146
- secret: env.JWT_SECRET, // Direto! (string)
147
- expiresIn: env.get('JWT_EXPIRES_IN', '24h'),
148
- algorithm: env.get('JWT_ALGORITHM', 'HS256'),
149
- issuer: env.get('JWT_ISSUER')
150
- }
151
- } : {}),
152
-
153
- // Optional email configuration
154
- ...(env.has('SMTP_HOST') ? {
155
- email: {
156
- host: env.SMTP_HOST, // Direto! (string)
157
- port: env.SMTP_PORT, // Direto! (number)
158
- user: env.SMTP_USER, // Direto! (string)
159
- password: env.SMTP_PASSWORD, // Direto! (string)
160
- secure: env.SMTP_SECURE, // Direto! (boolean)
161
- from: env.get('SMTP_FROM')
162
- }
163
- } : {}),
164
-
165
- // Optional storage configuration
166
- ...(env.has('UPLOAD_PATH') || env.has('STORAGE_PROVIDER') ? {
296
+ // Optional configurations (only included if env vars are set)
297
+ ...(databaseConfig ? { database: databaseConfig } : {}),
298
+ ...(authConfig ? { auth: authConfig } : {}),
299
+ ...(emailConfig ? { email: emailConfig } : {}),
300
+ ...(storageConfig ? {
167
301
  storage: {
168
- uploadPath: env.get('UPLOAD_PATH'),
169
- maxFileSize: env.get('MAX_FILE_SIZE', 10485760), // 10MB default
170
- allowedTypes: env.get('ALLOWED_FILE_TYPES', []), // array casting
171
- provider: env.get('STORAGE_PROVIDER', 'local'),
172
- config: env.get('STORAGE_CONFIG', {}) // object casting
302
+ ...storageConfig,
303
+ config: env.get('STORAGE_CONFIG', {})
173
304
  }
174
305
  } : {}),
175
306
 
@@ -192,6 +323,7 @@ export const config: FluxStackConfig = {
192
323
  proxy: { target: 'http://localhost:3000' },
193
324
  build: {
194
325
  sourceMaps: true,
326
+ minify: false,
195
327
  target: 'es2020',
196
328
  outDir: 'dist'
197
329
  }
@@ -200,12 +332,15 @@ export const config: FluxStackConfig = {
200
332
  target: 'bun',
201
333
  outDir: 'dist',
202
334
  optimization: {
335
+ minify: false,
203
336
  compress: false,
204
337
  treeshake: false,
205
338
  splitChunks: false,
206
339
  bundleAnalyzer: false
207
340
  },
208
341
  sourceMaps: true,
342
+ minify: false,
343
+ treeshake: false,
209
344
  clean: true
210
345
  },
211
346
  monitoring: {
@@ -243,6 +378,7 @@ export const config: FluxStackConfig = {
243
378
  proxy: { target: 'http://localhost:3000' },
244
379
  build: {
245
380
  sourceMaps: false,
381
+ minify: true,
246
382
  target: 'es2020',
247
383
  outDir: 'dist'
248
384
  }
@@ -251,12 +387,15 @@ export const config: FluxStackConfig = {
251
387
  target: 'bun',
252
388
  outDir: 'dist',
253
389
  optimization: {
390
+ minify: true,
254
391
  treeshake: false,
255
392
  compress: false,
256
393
  splitChunks: false,
257
394
  bundleAnalyzer: false
258
395
  },
259
396
  sourceMaps: false,
397
+ minify: true,
398
+ treeshake: false,
260
399
  clean: true
261
400
  },
262
401
  monitoring: {
@@ -300,7 +439,7 @@ export const config: FluxStackConfig = {
300
439
  client: {
301
440
  port: 0, // Use random available port
302
441
  proxy: { target: 'http://localhost:3000' },
303
- build: { sourceMaps: true, target: 'es2020', outDir: 'dist' }
442
+ build: { sourceMaps: true, minify: false, target: 'es2020', outDir: 'dist' }
304
443
  },
305
444
  monitoring: {
306
445
  enabled: false,