create-fluxstack 1.0.22 → 1.4.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 (82) hide show
  1. package/app/server/backend-only.ts +5 -5
  2. package/app/server/index.ts +63 -54
  3. package/app/server/live/FluxStackConfig.ts +43 -39
  4. package/app/server/live/SystemMonitorIntegration.ts +2 -2
  5. package/app/server/live/register-components.ts +6 -26
  6. package/app/server/middleware/errorHandling.ts +6 -4
  7. package/app/server/routes/config.ts +145 -0
  8. package/app/server/routes/index.ts +5 -3
  9. package/config/app.config.ts +113 -0
  10. package/config/build.config.ts +24 -0
  11. package/config/database.config.ts +99 -0
  12. package/config/index.ts +68 -0
  13. package/config/logger.config.ts +27 -0
  14. package/config/runtime.config.ts +92 -0
  15. package/config/server.config.ts +46 -0
  16. package/config/services.config.ts +130 -0
  17. package/config/system.config.ts +105 -0
  18. package/core/build/bundler.ts +53 -5
  19. package/core/build/flux-plugins-generator.ts +315 -0
  20. package/core/build/index.ts +11 -7
  21. package/core/build/live-components-generator.ts +231 -0
  22. package/core/build/optimizer.ts +2 -54
  23. package/core/cli/index.ts +31 -13
  24. package/core/config/env.ts +38 -94
  25. package/core/config/runtime-config.ts +61 -58
  26. package/core/config/schema.ts +1 -0
  27. package/core/framework/server.ts +55 -11
  28. package/core/plugins/built-in/index.ts +7 -17
  29. package/core/plugins/built-in/static/index.ts +24 -10
  30. package/core/plugins/built-in/swagger/index.ts +228 -228
  31. package/core/plugins/built-in/vite/index.ts +374 -358
  32. package/core/plugins/dependency-manager.ts +5 -5
  33. package/core/plugins/manager.ts +57 -14
  34. package/core/plugins/registry.ts +3 -3
  35. package/core/server/index.ts +0 -1
  36. package/core/server/live/ComponentRegistry.ts +34 -8
  37. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  38. package/core/server/live/websocket-plugin.ts +434 -434
  39. package/core/server/middleware/README.md +488 -0
  40. package/core/server/middleware/elysia-helpers.ts +227 -0
  41. package/core/server/middleware/index.ts +25 -9
  42. package/core/server/plugins/static-files-plugin.ts +231 -231
  43. package/core/utils/config-schema.ts +484 -0
  44. package/core/utils/env.ts +306 -0
  45. package/core/utils/helpers.ts +9 -3
  46. package/core/utils/logger/colors.ts +114 -0
  47. package/core/utils/logger/config.ts +35 -0
  48. package/core/utils/logger/formatter.ts +82 -0
  49. package/core/utils/logger/group-logger.ts +101 -0
  50. package/core/utils/logger/index.ts +199 -250
  51. package/core/utils/logger/stack-trace.ts +92 -0
  52. package/core/utils/logger/startup-banner.ts +92 -0
  53. package/core/utils/logger/winston-logger.ts +152 -0
  54. package/core/utils/version.ts +5 -0
  55. package/create-fluxstack.ts +1 -0
  56. package/fluxstack.config.ts +6 -12
  57. package/package.json +117 -114
  58. package/plugins/crypto-auth/README.md +238 -0
  59. package/plugins/crypto-auth/client/CryptoAuthClient.ts +325 -0
  60. package/plugins/crypto-auth/client/components/AuthProvider.tsx +190 -0
  61. package/plugins/crypto-auth/client/components/LoginButton.tsx +155 -0
  62. package/plugins/crypto-auth/client/components/ProtectedRoute.tsx +109 -0
  63. package/plugins/crypto-auth/client/components/SessionInfo.tsx +242 -0
  64. package/plugins/crypto-auth/client/components/index.ts +15 -0
  65. package/plugins/crypto-auth/client/index.ts +12 -0
  66. package/plugins/crypto-auth/index.ts +230 -0
  67. package/plugins/crypto-auth/package.json +65 -0
  68. package/plugins/crypto-auth/plugin.json +29 -0
  69. package/plugins/crypto-auth/server/AuthMiddleware.ts +237 -0
  70. package/plugins/crypto-auth/server/CryptoAuthService.ts +293 -0
  71. package/plugins/crypto-auth/server/index.ts +9 -0
  72. package/vite.config.ts +16 -0
  73. package/core/config/env-dynamic.ts +0 -326
  74. package/core/plugins/built-in/logger/index.ts +0 -180
  75. package/core/server/plugins/logger.ts +0 -47
  76. package/core/utils/env-runtime-v2.ts +0 -232
  77. package/core/utils/env-runtime.ts +0 -259
  78. package/core/utils/logger/formatters.ts +0 -222
  79. package/core/utils/logger/middleware.ts +0 -253
  80. package/core/utils/logger/performance.ts +0 -384
  81. package/core/utils/logger/transports.ts +0 -365
  82. package/core/utils/logger.ts +0 -106
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Application Configuration
3
+ * Laravel-style declarative config with validation
4
+ */
5
+
6
+ import { defineConfig, config } from '@/core/utils/config-schema'
7
+
8
+ /**
9
+ * App configuration schema
10
+ */
11
+ const appConfigSchema = {
12
+ // App basics
13
+ name: config.string('APP_NAME', 'FluxStack', true),
14
+
15
+ version: {
16
+ type: 'string' as const,
17
+ env: 'APP_VERSION',
18
+ default: '1.0.0',
19
+ validate: (value: string) => /^\d+\.\d+\.\d+$/.test(value) || 'Version must be semver format (e.g., 1.0.0)'
20
+ },
21
+
22
+ description: config.string('APP_DESCRIPTION', 'A FluxStack application'),
23
+
24
+ // Environment
25
+ env: config.enum('NODE_ENV', ['development', 'production', 'test'] as const, 'development', true),
26
+
27
+ debug: config.boolean('DEBUG', false),
28
+
29
+ // Server
30
+ port: {
31
+ type: 'number' as const,
32
+ env: 'PORT',
33
+ default: 3000,
34
+ required: true,
35
+ validate: (value: number) => {
36
+ if (value < 1 || value > 65535) {
37
+ return 'Port must be between 1 and 65535'
38
+ }
39
+ return true
40
+ }
41
+ },
42
+
43
+ host: config.string('HOST', 'localhost', true),
44
+
45
+ apiPrefix: {
46
+ type: 'string' as const,
47
+ env: 'API_PREFIX',
48
+ default: '/api',
49
+ validate: (value: string) => value.startsWith('/') || 'API prefix must start with /'
50
+ },
51
+
52
+ // URLs
53
+ url: config.string('APP_URL', undefined, false),
54
+
55
+ // Features
56
+ enableSwagger: config.boolean('ENABLE_SWAGGER', true),
57
+ enableMetrics: config.boolean('ENABLE_METRICS', false),
58
+ enableMonitoring: config.boolean('ENABLE_MONITORING', false),
59
+
60
+ // Client
61
+ clientPort: config.number('VITE_PORT', 5173),
62
+
63
+ // Logging
64
+ logLevel: config.enum('LOG_LEVEL', ['debug', 'info', 'warn', 'error'] as const, 'info'),
65
+ logFormat: config.enum('LOG_FORMAT', ['json', 'pretty'] as const, 'pretty'),
66
+
67
+ // CORS
68
+ corsOrigins: config.array('CORS_ORIGINS', ['*']),
69
+ corsMethods: config.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
70
+ corsHeaders: config.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
71
+ corsCredentials: config.boolean('CORS_CREDENTIALS', false),
72
+
73
+ // Security
74
+ trustProxy: config.boolean('TRUST_PROXY', false),
75
+
76
+ sessionSecret: {
77
+ type: 'string' as const,
78
+ env: 'SESSION_SECRET',
79
+ default: undefined,
80
+ required: false,
81
+ validate: (value: string) => {
82
+ if (!value) return true // Optional
83
+ if (value.length < 32) {
84
+ return 'Session secret must be at least 32 characters'
85
+ }
86
+ return true
87
+ }
88
+ }
89
+ } as const
90
+
91
+ export const appConfig = defineConfig(appConfigSchema)
92
+
93
+ // Export type for use in other files
94
+ export type AppConfig = typeof appConfig
95
+
96
+ /**
97
+ * Type-safe environment type
98
+ * Use this when you need the literal type explicitly
99
+ */
100
+ export type Environment = typeof appConfig.env
101
+
102
+ /**
103
+ * Type-safe log level type
104
+ */
105
+ export type LogLevel = typeof appConfig.logLevel
106
+
107
+ /**
108
+ * Type-safe log format type
109
+ */
110
+ export type LogFormat = typeof appConfig.logFormat
111
+
112
+ // Export default
113
+ export default appConfig
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Build & Client Configuration
3
+ * Declarative build and client config for FluxStack framework
4
+ */
5
+
6
+ import { defineConfig, config } from '@/core/utils/config-schema'
7
+
8
+ export const buildConfig = defineConfig({
9
+ // Client build settings
10
+ clientBuildDir: config.string('CLIENT_BUILD_DIR', 'dist/client'),
11
+ clientSourceMaps: config.boolean('CLIENT_SOURCEMAPS', false),
12
+ clientMinify: config.boolean('CLIENT_MINIFY', true),
13
+ clientTarget: config.string('CLIENT_TARGET', 'es2020'),
14
+
15
+ // API proxy settings
16
+ apiUrl: config.string('API_URL', 'http://localhost:3000'),
17
+ proxyChangeOrigin: config.boolean('PROXY_CHANGE_ORIGIN', true),
18
+
19
+ // Monitoring
20
+ monitoringEnabled: config.boolean('MONITORING_ENABLED', false)
21
+ })
22
+
23
+ export type BuildConfig = typeof buildConfig
24
+ export default buildConfig
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Database Configuration
3
+ * Laravel-style declarative config with validation
4
+ */
5
+
6
+ import { defineConfig, config } from '@/core/utils/config-schema'
7
+
8
+ /**
9
+ * Database configuration schema
10
+ */
11
+ export const databaseConfig = defineConfig({
12
+ // Connection
13
+ url: {
14
+ type: 'string',
15
+ env: 'DATABASE_URL',
16
+ default: undefined,
17
+ required: false,
18
+ validate: (value) => {
19
+ if (!value) return true // Optional
20
+ if (!value.includes('://')) {
21
+ return 'DATABASE_URL must be a valid connection string (e.g., postgres://...)'
22
+ }
23
+ return true
24
+ },
25
+ description: 'Full database connection URL (overrides individual settings)'
26
+ },
27
+
28
+ host: config.string('DB_HOST', 'localhost'),
29
+
30
+ port: config.number('DB_PORT', 5432),
31
+
32
+ database: {
33
+ type: 'string',
34
+ env: 'DB_NAME',
35
+ default: undefined,
36
+ required: false,
37
+ description: 'Database name'
38
+ },
39
+
40
+ user: {
41
+ type: 'string',
42
+ env: 'DB_USER',
43
+ default: undefined,
44
+ required: false
45
+ },
46
+
47
+ password: {
48
+ type: 'string',
49
+ env: 'DB_PASSWORD',
50
+ default: undefined,
51
+ required: false
52
+ },
53
+
54
+ // Connection pool
55
+ poolMin: {
56
+ type: 'number',
57
+ env: 'DB_POOL_MIN',
58
+ default: 2,
59
+ validate: (value) => value >= 0 || 'Pool min must be >= 0'
60
+ },
61
+
62
+ poolMax: {
63
+ type: 'number',
64
+ env: 'DB_POOL_MAX',
65
+ default: 10,
66
+ validate: (value) => value > 0 || 'Pool max must be > 0'
67
+ },
68
+
69
+ // SSL
70
+ ssl: config.boolean('DB_SSL', false),
71
+
72
+ // Timeouts
73
+ connectionTimeout: {
74
+ type: 'number',
75
+ env: 'DB_CONNECTION_TIMEOUT',
76
+ default: 30000,
77
+ description: 'Connection timeout in milliseconds'
78
+ },
79
+
80
+ queryTimeout: {
81
+ type: 'number',
82
+ env: 'DB_QUERY_TIMEOUT',
83
+ default: 60000,
84
+ description: 'Query timeout in milliseconds'
85
+ },
86
+
87
+ // Features
88
+ enableLogging: config.boolean('DB_ENABLE_LOGGING', false),
89
+
90
+ enableMigrations: config.boolean('DB_ENABLE_MIGRATIONS', true),
91
+
92
+ migrationsTable: config.string('DB_MIGRATIONS_TABLE', 'migrations')
93
+ })
94
+
95
+ // Export type
96
+ export type DatabaseConfig = typeof databaseConfig
97
+
98
+ // Export default
99
+ export default databaseConfig
@@ -0,0 +1,68 @@
1
+ /**
2
+ * ⚡ FluxStack Configuration Index
3
+ *
4
+ * Centralized configuration using Laravel-style declarative schemas
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { appConfig, databaseConfig, servicesConfig } from '@/config'
9
+ *
10
+ * // All configs are type-safe and validated!
11
+ * console.log(appConfig.name) // string
12
+ * console.log(appConfig.port) // number
13
+ * console.log(appConfig.debug) // boolean
14
+ *
15
+ * // Nested configs
16
+ * console.log(servicesConfig.email.host) // string
17
+ * console.log(servicesConfig.jwt.secret) // string
18
+ * ```
19
+ */
20
+
21
+ export { appConfig } from './app.config'
22
+ export { databaseConfig } from './database.config'
23
+ export { servicesConfig } from './services.config'
24
+ export { serverConfig } from './server.config'
25
+ export { loggerConfig } from './logger.config'
26
+ export { buildConfig } from './build.config'
27
+ export { appRuntimeConfig } from './runtime.config'
28
+ export { systemConfig, systemRuntimeInfo } from './system.config'
29
+
30
+ // Re-export types
31
+ export type { AppConfig } from './app.config'
32
+ export type { DatabaseConfig } from './database.config'
33
+ export type { ServerConfig } from './server.config'
34
+ export type { LoggerConfig } from './logger.config'
35
+ export type { BuildConfig } from './build.config'
36
+ export type { SystemConfig, SystemRuntimeInfo } from './system.config'
37
+ export type {
38
+ EmailConfig,
39
+ JWTConfig,
40
+ StorageConfig,
41
+ RedisConfig
42
+ } from './services.config'
43
+
44
+ /**
45
+ * All configs in one object
46
+ */
47
+ import { appConfig } from './app.config'
48
+ import { databaseConfig } from './database.config'
49
+ import { servicesConfig } from './services.config'
50
+ import { serverConfig } from './server.config'
51
+ import { loggerConfig } from './logger.config'
52
+ import { buildConfig } from './build.config'
53
+ import { appRuntimeConfig } from './runtime.config'
54
+ import { systemConfig, systemRuntimeInfo } from './system.config'
55
+
56
+ export const config = {
57
+ app: appConfig,
58
+ database: databaseConfig,
59
+ services: servicesConfig,
60
+ server: serverConfig,
61
+ logger: loggerConfig,
62
+ build: buildConfig,
63
+ runtime: appRuntimeConfig,
64
+ system: systemConfig,
65
+ systemRuntime: systemRuntimeInfo
66
+ }
67
+
68
+ export default config
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Logger Configuration
3
+ * Declarative logger config using FluxStack config system
4
+ */
5
+
6
+ import { defineConfig, config } from '@/core/utils/config-schema'
7
+
8
+ export const loggerConfig = defineConfig({
9
+ // Log level
10
+ level: config.enum('LOG_LEVEL', ['debug', 'info', 'warn', 'error'] as const, 'info'),
11
+
12
+ // Format settings
13
+ dateFormat: config.string('LOG_DATE_FORMAT', 'YYYY-MM-DD HH:mm:ss'),
14
+ objectDepth: config.number('LOG_OBJECT_DEPTH', 4),
15
+
16
+ // File logging
17
+ logToFile: config.boolean('LOG_TO_FILE', false),
18
+ maxSize: config.string('LOG_MAX_SIZE', '20m'),
19
+ maxFiles: config.string('LOG_MAX_FILES', '14d'),
20
+
21
+ // Display options
22
+ enableColors: config.boolean('LOG_COLORS', true),
23
+ enableStackTrace: config.boolean('LOG_STACK_TRACE', true)
24
+ })
25
+
26
+ export type LoggerConfig = typeof loggerConfig
27
+ export default loggerConfig
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Runtime-Reloadable Configuration
3
+ * Configs that can be reloaded without server restart
4
+ */
5
+
6
+ import { defineReactiveConfig, config } from '@/core/utils/config-schema'
7
+
8
+ /**
9
+ * Runtime app configuration
10
+ * Can be reloaded via appRuntimeConfig.reload()
11
+ */
12
+ export const appRuntimeConfig = defineReactiveConfig({
13
+ // Features that can be toggled in runtime
14
+ enableSwagger: config.boolean('ENABLE_SWAGGER', true),
15
+ enableMetrics: config.boolean('ENABLE_METRICS', false),
16
+ enableMonitoring: config.boolean('ENABLE_MONITORING', false),
17
+ enableDebugMode: config.boolean('DEBUG', false),
18
+
19
+ // Logging level can be changed in runtime
20
+ logLevel: config.enum(
21
+ 'LOG_LEVEL',
22
+ ['debug', 'info', 'warn', 'error'] as const,
23
+ 'info'
24
+ ),
25
+
26
+ logFormat: config.enum(
27
+ 'LOG_FORMAT',
28
+ ['json', 'pretty'] as const,
29
+ 'pretty'
30
+ ),
31
+
32
+ // Rate limiting
33
+ rateLimitEnabled: config.boolean('RATE_LIMIT_ENABLED', true),
34
+
35
+ rateLimitMax: {
36
+ type: 'number' as const,
37
+ env: 'RATE_LIMIT_MAX',
38
+ default: 100,
39
+ validate: (value: number) => value > 0 || 'Rate limit must be positive'
40
+ },
41
+
42
+ rateLimitWindow: {
43
+ type: 'number' as const,
44
+ env: 'RATE_LIMIT_WINDOW',
45
+ default: 60000,
46
+ description: 'Rate limit window in milliseconds'
47
+ },
48
+
49
+ // Request timeout
50
+ requestTimeout: {
51
+ type: 'number' as const,
52
+ env: 'REQUEST_TIMEOUT',
53
+ default: 30000,
54
+ validate: (value: number) => value > 0 || 'Timeout must be positive'
55
+ },
56
+
57
+ // Max upload size
58
+ maxUploadSize: {
59
+ type: 'number' as const,
60
+ env: 'MAX_UPLOAD_SIZE',
61
+ default: 10485760, // 10MB
62
+ validate: (value: number) => value > 0 || 'Max upload size must be positive'
63
+ },
64
+
65
+ // Allowed origins (can be updated in runtime)
66
+ corsOrigins: config.array('CORS_ORIGINS', ['*']),
67
+
68
+ // Maintenance mode
69
+ maintenanceMode: config.boolean('MAINTENANCE_MODE', false),
70
+
71
+ maintenanceMessage: config.string(
72
+ 'MAINTENANCE_MESSAGE',
73
+ 'System is under maintenance. Please try again later.'
74
+ )
75
+ })
76
+
77
+ /**
78
+ * Setup config watcher with logging
79
+ */
80
+ appRuntimeConfig.watch((newConfig) => {
81
+ console.log('🔄 Runtime config reloaded:')
82
+ console.log(' Debug:', newConfig.enableDebugMode)
83
+ console.log(' Log Level:', newConfig.logLevel)
84
+ console.log(' Maintenance:', newConfig.maintenanceMode)
85
+ })
86
+
87
+ /**
88
+ * Export type
89
+ */
90
+ export type AppRuntimeConfig = typeof appRuntimeConfig.values
91
+
92
+ export default appRuntimeConfig
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Server Configuration
3
+ * Declarative server config using FluxStack config system
4
+ */
5
+
6
+ import { defineConfig, config } from '@/core/utils/config-schema'
7
+
8
+ const serverConfigSchema = {
9
+ // Server basics
10
+ port: config.number('PORT', 3000, true),
11
+ host: config.string('HOST', 'localhost', true),
12
+ apiPrefix: config.string('API_PREFIX', '/api'),
13
+
14
+ // CORS configuration
15
+ corsOrigins: config.array('CORS_ORIGINS', ['http://localhost:3000', 'http://localhost:5173']),
16
+ corsMethods: config.array('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
17
+ corsHeaders: config.array('CORS_HEADERS', ['Content-Type', 'Authorization']),
18
+ corsCredentials: config.boolean('CORS_CREDENTIALS', false),
19
+ corsMaxAge: config.number('CORS_MAX_AGE', 86400),
20
+
21
+ // Client config
22
+ clientPort: config.number('VITE_PORT', 5173),
23
+ clientTarget: config.string('CLIENT_TARGET', 'es2020'),
24
+ clientOutDir: config.string('CLIENT_OUTDIR', 'dist'),
25
+ clientSourceMaps: config.boolean('CLIENT_SOURCEMAPS', false),
26
+
27
+ // Backend-only mode
28
+ backendPort: config.number('BACKEND_PORT', 3001),
29
+
30
+ // App info
31
+ appName: config.string('FLUXSTACK_APP_NAME', 'FluxStack'),
32
+ appVersion: config.string('FLUXSTACK_APP_VERSION', '1.0.0'),
33
+
34
+ // Features
35
+ enableSwagger: config.boolean('ENABLE_SWAGGER', true),
36
+ enableMetrics: config.boolean('ENABLE_METRICS', false),
37
+ enableMonitoring: config.boolean('ENABLE_MONITORING', false),
38
+
39
+ // Vite/Development
40
+ enableViteProxyLogs: config.boolean('ENABLE_VITE_PROXY_LOGS', false)
41
+ } as const
42
+
43
+ export const serverConfig = defineConfig(serverConfigSchema)
44
+
45
+ export type ServerConfig = typeof serverConfig
46
+ export default serverConfig
@@ -0,0 +1,130 @@
1
+ /**
2
+ * External Services Configuration
3
+ * Laravel-style declarative config for third-party services
4
+ */
5
+
6
+ import { defineConfig, defineNestedConfig, config } from '@/core/utils/config-schema'
7
+
8
+ /**
9
+ * Email service configuration
10
+ */
11
+ const emailSchema = {
12
+ // SMTP
13
+ host: config.string('SMTP_HOST'),
14
+
15
+ port: {
16
+ type: 'number' as const,
17
+ env: 'SMTP_PORT',
18
+ default: 587,
19
+ validate: (value: number) => value > 0 || 'SMTP port must be positive'
20
+ },
21
+
22
+ user: config.string('SMTP_USER'),
23
+ password: config.string('SMTP_PASSWORD'),
24
+
25
+ secure: config.boolean('SMTP_SECURE', false),
26
+
27
+ from: {
28
+ type: 'string' as const,
29
+ env: 'SMTP_FROM',
30
+ default: 'noreply@example.com',
31
+ validate: (value: string) => {
32
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
33
+ return emailRegex.test(value) || 'From email must be valid'
34
+ }
35
+ },
36
+
37
+ replyTo: config.string('SMTP_REPLY_TO')
38
+ }
39
+
40
+ /**
41
+ * JWT authentication configuration
42
+ */
43
+ const jwtSchema = {
44
+ secret: {
45
+ type: 'string' as const,
46
+ env: 'JWT_SECRET',
47
+ default: undefined,
48
+ required: false,
49
+ validate: (value: string) => {
50
+ if (!value) return true // Optional
51
+ if (value.length < 32) {
52
+ return 'JWT secret must be at least 32 characters for security'
53
+ }
54
+ return true
55
+ }
56
+ },
57
+
58
+ expiresIn: config.string('JWT_EXPIRES_IN', '24h'),
59
+
60
+ algorithm: config.enum(
61
+ 'JWT_ALGORITHM',
62
+ ['HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512'] as const,
63
+ 'HS256'
64
+ ),
65
+
66
+ issuer: config.string('JWT_ISSUER', 'fluxstack'),
67
+
68
+ audience: config.string('JWT_AUDIENCE')
69
+ }
70
+
71
+ /**
72
+ * Storage configuration
73
+ */
74
+ const storageSchema = {
75
+ provider: config.enum(
76
+ 'STORAGE_PROVIDER',
77
+ ['local', 's3', 'gcs', 'azure'] as const,
78
+ 'local'
79
+ ),
80
+
81
+ uploadPath: config.string('UPLOAD_PATH', './uploads'),
82
+
83
+ maxFileSize: {
84
+ type: 'number' as const,
85
+ env: 'MAX_FILE_SIZE',
86
+ default: 10485760, // 10MB
87
+ validate: (value: number) => value > 0 || 'Max file size must be positive'
88
+ },
89
+
90
+ allowedTypes: config.array('ALLOWED_FILE_TYPES', ['image/*', 'application/pdf']),
91
+
92
+ // S3 specific
93
+ s3Bucket: config.string('S3_BUCKET'),
94
+ s3Region: config.string('S3_REGION', 'us-east-1'),
95
+ s3AccessKey: config.string('S3_ACCESS_KEY'),
96
+ s3SecretKey: config.string('S3_SECRET_KEY')
97
+ }
98
+
99
+ /**
100
+ * Redis configuration
101
+ */
102
+ const redisSchema = {
103
+ host: config.string('REDIS_HOST', 'localhost'),
104
+ port: config.number('REDIS_PORT', 6379),
105
+ password: config.string('REDIS_PASSWORD'),
106
+ db: config.number('REDIS_DB', 0),
107
+
108
+ keyPrefix: config.string('REDIS_KEY_PREFIX', 'fluxstack:'),
109
+
110
+ enableTls: config.boolean('REDIS_TLS', false)
111
+ }
112
+
113
+ /**
114
+ * Export all service configs as nested object
115
+ */
116
+ export const servicesConfig = defineNestedConfig({
117
+ email: emailSchema,
118
+ jwt: jwtSchema,
119
+ storage: storageSchema,
120
+ redis: redisSchema
121
+ })
122
+
123
+ // Export types
124
+ export type EmailConfig = typeof servicesConfig.email
125
+ export type JWTConfig = typeof servicesConfig.jwt
126
+ export type StorageConfig = typeof servicesConfig.storage
127
+ export type RedisConfig = typeof servicesConfig.redis
128
+
129
+ // Export default
130
+ export default servicesConfig