create-fluxstack 1.17.0 → 1.18.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 (93) hide show
  1. package/LLMD/resources/live-auth.md +462 -465
  2. package/app/client/.live-stubs/LiveAdminPanel.js +15 -0
  3. package/app/client/.live-stubs/LiveCounter.js +9 -0
  4. package/app/client/.live-stubs/LiveForm.js +11 -0
  5. package/app/client/.live-stubs/LiveLocalCounter.js +8 -0
  6. package/app/client/.live-stubs/LivePingPong.js +10 -0
  7. package/app/client/.live-stubs/LiveRoomChat.js +11 -0
  8. package/app/client/.live-stubs/LiveSharedCounter.js +10 -0
  9. package/app/client/.live-stubs/LiveUpload.js +15 -0
  10. package/app/client/src/App.tsx +45 -3
  11. package/app/client/src/components/AppLayout.tsx +10 -1
  12. package/app/client/src/components/ErrorBoundary.tsx +117 -0
  13. package/app/client/src/components/LiveErrorBoundary.tsx +87 -0
  14. package/app/client/src/components/LiveUploadWidget.tsx +10 -14
  15. package/app/client/src/lib/eden-api.ts +6 -0
  16. package/app/client/src/lib/plugin-hooks.ts +82 -0
  17. package/app/client/src/live/AuthDemo.tsx +0 -1
  18. package/app/client/src/live/FormDemo.tsx +1 -1
  19. package/app/client/src/live/PingPongDemo.tsx +4 -1
  20. package/app/client/src/live/RoomChatDemo.tsx +90 -50
  21. package/app/client/src/live/SharedCounterDemo.tsx +5 -0
  22. package/app/server/auth/AuthManager.ts +24 -0
  23. package/app/server/auth/contracts.ts +12 -1
  24. package/app/server/auth/errors.ts +84 -0
  25. package/app/server/auth/guards/TokenGuard.ts +5 -2
  26. package/app/server/auth/index.ts +1 -1
  27. package/app/server/auth/providers/InMemoryProvider.ts +1 -1
  28. package/app/server/index.ts +3 -4
  29. package/app/server/live/LiveAdminPanel.ts +8 -8
  30. package/app/server/live/LiveForm.ts +1 -1
  31. package/app/server/live/LiveProtectedChat.ts +5 -5
  32. package/app/server/live/LiveRoomChat.ts +50 -28
  33. package/app/server/live/LiveUpload.ts +17 -3
  34. package/app/server/live/auto-generated-components.ts +26 -0
  35. package/app/server/live/rooms/ChatRoom.ts +17 -2
  36. package/app/server/routes/auth.routes.ts +29 -20
  37. package/app/server/routes/index.ts +9 -0
  38. package/app/server/routes/room.routes.ts +6 -6
  39. package/config/index.ts +3 -3
  40. package/config/system/app.config.ts +1 -1
  41. package/config/system/auth.config.ts +1 -1
  42. package/config/system/build.config.ts +8 -6
  43. package/config/system/client.config.ts +6 -4
  44. package/config/system/database.config.ts +1 -1
  45. package/config/system/logger.config.ts +1 -1
  46. package/config/system/monitoring.config.ts +6 -4
  47. package/config/system/plugins.config.ts +1 -1
  48. package/config/system/runtime.config.ts +1 -1
  49. package/config/system/server.config.ts +1 -1
  50. package/config/system/services.config.ts +1 -1
  51. package/config/system/session.config.ts +3 -3
  52. package/config/system/system.config.ts +1 -1
  53. package/core/build/vite-plugins.ts +3 -2
  54. package/core/cli/generators/plugin.ts +1 -1
  55. package/core/config/index.ts +8 -1
  56. package/core/framework/server.ts +9 -5
  57. package/core/index.ts +1 -1
  58. package/core/plugins/index.ts +1 -1
  59. package/core/plugins/manager.ts +5 -1
  60. package/core/plugins/types.ts +17 -1
  61. package/core/server/index.ts +5 -2
  62. package/core/server/live/index.ts +8 -71
  63. package/core/server/plugin-client-hooks.ts +97 -0
  64. package/core/types/types.ts +1 -0
  65. package/core/utils/version.ts +1 -1
  66. package/create-fluxstack.ts +1 -1
  67. package/package.json +8 -5
  68. package/src/client/components/ui/StatusBadge.tsx +23 -0
  69. package/core/utils/config-schema.ts +0 -480
  70. package/core/utils/env.ts +0 -305
  71. package/plugins/crypto-auth/README.md +0 -788
  72. package/plugins/crypto-auth/ai-context.md +0 -1282
  73. package/plugins/crypto-auth/cli/make-protected-route.command.ts +0 -383
  74. package/plugins/crypto-auth/client/CryptoAuthClient.ts +0 -302
  75. package/plugins/crypto-auth/client/components/AuthProvider.tsx +0 -131
  76. package/plugins/crypto-auth/client/components/LoginButton.tsx +0 -138
  77. package/plugins/crypto-auth/client/components/ProtectedRoute.tsx +0 -89
  78. package/plugins/crypto-auth/client/components/index.ts +0 -12
  79. package/plugins/crypto-auth/client/index.ts +0 -12
  80. package/plugins/crypto-auth/config/index.ts +0 -34
  81. package/plugins/crypto-auth/index.ts +0 -173
  82. package/plugins/crypto-auth/package.json +0 -66
  83. package/plugins/crypto-auth/server/AuthMiddleware.ts +0 -181
  84. package/plugins/crypto-auth/server/CryptoAuthLiveProvider.ts +0 -58
  85. package/plugins/crypto-auth/server/CryptoAuthService.ts +0 -186
  86. package/plugins/crypto-auth/server/index.ts +0 -25
  87. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +0 -66
  88. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +0 -26
  89. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +0 -77
  90. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +0 -45
  91. package/plugins/crypto-auth/server/middlewares/helpers.ts +0 -155
  92. package/plugins/crypto-auth/server/middlewares/index.ts +0 -22
  93. package/plugins/crypto-auth/server/middlewares.ts +0 -19
package/core/utils/env.ts DELETED
@@ -1,305 +0,0 @@
1
- /**
2
- * ⚡ FluxStack Unified Environment Loader
3
- *
4
- * Single source of truth for environment variables with:
5
- * - Automatic type casting
6
- * - Build-safe dynamic access (prevents Bun inlining)
7
- * - Simple, intuitive API
8
- * - TypeScript type inference
9
- *
10
- * @example
11
- * ```ts
12
- * import { env } from '@core/utils/env'
13
- *
14
- * const port = env.PORT // number (3000)
15
- * const debug = env.DEBUG // boolean (false)
16
- * const origins = env.CORS_ORIGINS // string[] (['*'])
17
- *
18
- * // Custom vars with smart casting
19
- * const timeout = env.get('TIMEOUT', 5000) // number
20
- * const enabled = env.get('FEATURE_X', false) // boolean
21
- * const tags = env.get('TAGS', ['api']) // string[]
22
- * ```
23
- */
24
-
25
- /**
26
- * Smart environment loader with dynamic access
27
- * Uses Bun.env (runtime) → process.env (fallback) → eval (last resort)
28
- */
29
- class EnvLoader {
30
- private cache = new Map<string, unknown>()
31
- private accessor: () => Record<string, string | undefined>
32
-
33
- constructor() {
34
- this.accessor = this.createAccessor()
35
- }
36
-
37
- /**
38
- * Create dynamic accessor to prevent build-time inlining
39
- */
40
- private createAccessor(): () => Record<string, string | undefined> {
41
- const global = globalThis as unknown as Record<string, Record<string, unknown> | undefined>
42
-
43
- return () => {
44
- // Try Bun.env first (most reliable in Bun)
45
- const bun = global['Bun'] as Record<string, unknown> | undefined
46
- if (bun?.['env']) {
47
- return bun['env'] as Record<string, string | undefined>
48
- }
49
-
50
- // Fallback to process.env
51
- const proc = global['process'] as Record<string, unknown> | undefined
52
- if (proc?.['env']) {
53
- return proc['env'] as Record<string, string | undefined>
54
- }
55
-
56
- return {}
57
- }
58
- }
59
-
60
- /**
61
- * Get environment variable with automatic type casting
62
- * Type is inferred from defaultValue
63
- */
64
- get<T>(key: string, defaultValue?: T): T {
65
- // Check cache first
66
- const cacheKey = `${key}:${typeof defaultValue}`
67
- if (this.cache.has(cacheKey)) {
68
- return this.cache.get(cacheKey) as T
69
- }
70
-
71
- const env = this.accessor()
72
- const value = env[key]
73
-
74
- if (!value || value === '') {
75
- this.cache.set(cacheKey, defaultValue as T)
76
- return defaultValue as T
77
- }
78
-
79
- // Auto-detect type from defaultValue
80
- let result: unknown = value
81
-
82
- if (typeof defaultValue === 'number') {
83
- const parsed = Number(value)
84
- result = isNaN(parsed) ? defaultValue : parsed
85
- } else if (typeof defaultValue === 'boolean') {
86
- result = ['true', '1', 'yes', 'on'].includes(value.toLowerCase())
87
- } else if (Array.isArray(defaultValue)) {
88
- result = value.split(',').map(v => v.trim()).filter(Boolean)
89
- } else if (typeof defaultValue === 'object' && defaultValue !== null) {
90
- try {
91
- result = JSON.parse(value)
92
- } catch {
93
- result = defaultValue
94
- }
95
- }
96
-
97
- this.cache.set(cacheKey, result)
98
- return result as T
99
- }
100
-
101
- /**
102
- * Check if environment variable exists and has a value
103
- */
104
- has(key: string): boolean {
105
- const env = this.accessor()
106
- const value = env[key]
107
- return value !== undefined && value !== ''
108
- }
109
-
110
- /**
111
- * Get all environment variables
112
- */
113
- all(): Record<string, string> {
114
- const env = this.accessor()
115
- const result: Record<string, string> = {}
116
-
117
- for (const [key, value] of Object.entries(env)) {
118
- if (value !== undefined && value !== '') {
119
- result[key] = value
120
- }
121
- }
122
-
123
- return result
124
- }
125
-
126
- /**
127
- * Require specific environment variables (throws if missing)
128
- */
129
- require(keys: string[]): void {
130
- const missing = keys.filter(key => !this.has(key))
131
- if (missing.length > 0) {
132
- throw new Error(
133
- `Missing required environment variables: ${missing.join(', ')}\n` +
134
- `Please set them in your .env file or environment.`
135
- )
136
- }
137
- }
138
-
139
- /**
140
- * Validate environment variable value
141
- */
142
- validate(key: string, validValues: string[]): void {
143
- const value = this.get(key, '')
144
- if (value && !validValues.includes(value)) {
145
- throw new Error(
146
- `Invalid value for ${key}: "${value}"\n` +
147
- `Valid values are: ${validValues.join(', ')}`
148
- )
149
- }
150
- }
151
-
152
- /**
153
- * Clear cache (useful for testing)
154
- */
155
- clearCache(): void {
156
- this.cache.clear()
157
- }
158
- }
159
-
160
- // Singleton instance
161
- const loader = new EnvLoader()
162
-
163
- /**
164
- * Unified environment variables API
165
- */
166
- export const env = {
167
- /**
168
- * Get environment variable with smart type casting
169
- * @example env.get('PORT', 3000) → number
170
- */
171
- get: <T>(key: string, defaultValue?: T): T => loader.get(key, defaultValue),
172
-
173
- /**
174
- * Check if environment variable exists
175
- */
176
- has: (key: string): boolean => loader.has(key),
177
-
178
- /**
179
- * Get all environment variables
180
- */
181
- all: (): Record<string, string> => loader.all(),
182
-
183
- /**
184
- * Require environment variables (throws if missing)
185
- */
186
- require: (keys: string[]): void => loader.require(keys),
187
-
188
- /**
189
- * Validate environment variable value
190
- */
191
- validate: (key: string, validValues: string[]): void => loader.validate(key, validValues),
192
-
193
- /**
194
- * Clear cache (for testing)
195
- */
196
- clearCache: (): void => loader.clearCache(),
197
-
198
- // Common environment variables with smart defaults
199
- get NODE_ENV() { return this.get('NODE_ENV', 'development') as 'development' | 'production' | 'test' },
200
- get PORT() { return this.get('PORT', 3000) },
201
- get HOST() { return this.get('HOST', 'localhost') },
202
- get DEBUG() { return this.get('DEBUG', false) },
203
- get LOG_LEVEL() { return this.get('LOG_LEVEL', 'info') as 'debug' | 'info' | 'warn' | 'error' },
204
- get LOG_FORMAT() { return this.get('LOG_FORMAT', 'pretty') as 'json' | 'pretty' },
205
-
206
- // API
207
- get API_PREFIX() { return this.get('API_PREFIX', '/api') },
208
- get VITE_PORT() { return this.get('VITE_PORT', 5173) },
209
-
210
- // CORS
211
- get CORS_ORIGINS() { return this.get('CORS_ORIGINS', ['*']) },
212
- get CORS_METHODS() { return this.get('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']) },
213
- get CORS_HEADERS() { return this.get('CORS_HEADERS', ['Content-Type', 'Authorization']) },
214
- get CORS_CREDENTIALS() { return this.get('CORS_CREDENTIALS', false) },
215
- get CORS_MAX_AGE() { return this.get('CORS_MAX_AGE', 86400) },
216
-
217
- // App
218
- get FLUXSTACK_APP_NAME() { return this.get('FLUXSTACK_APP_NAME', 'FluxStack') },
219
- get FLUXSTACK_APP_VERSION() {
220
- const { FLUXSTACK_VERSION } = require('./version')
221
- return this.get('FLUXSTACK_APP_VERSION', FLUXSTACK_VERSION)
222
- },
223
-
224
- // Features
225
- get ENABLE_MONITORING() { return this.get('ENABLE_MONITORING', false) },
226
- get ENABLE_SWAGGER() { return this.get('ENABLE_SWAGGER', true) },
227
- get ENABLE_METRICS() { return this.get('ENABLE_METRICS', false) },
228
-
229
- // Database
230
- get DATABASE_URL() { return this.get('DATABASE_URL', '') },
231
- get DB_HOST() { return this.get('DB_HOST', 'localhost') },
232
- get DB_PORT() { return this.get('DB_PORT', 5432) },
233
- get DB_NAME() { return this.get('DB_NAME', '') },
234
- get DB_USER() { return this.get('DB_USER', '') },
235
- get DB_PASSWORD() { return this.get('DB_PASSWORD', '') },
236
- get DB_SSL() { return this.get('DB_SSL', false) },
237
-
238
- // Auth
239
- get JWT_SECRET() { return this.get('JWT_SECRET', '') },
240
- get JWT_EXPIRES_IN() { return this.get('JWT_EXPIRES_IN', '24h') },
241
- get JWT_ALGORITHM() { return this.get('JWT_ALGORITHM', 'HS256') },
242
-
243
- // Email
244
- get SMTP_HOST() { return this.get('SMTP_HOST', '') },
245
- get SMTP_PORT() { return this.get('SMTP_PORT', 587) },
246
- get SMTP_USER() { return this.get('SMTP_USER', '') },
247
- get SMTP_PASSWORD() { return this.get('SMTP_PASSWORD', '') },
248
- get SMTP_SECURE() { return this.get('SMTP_SECURE', false) },
249
- }
250
-
251
- /**
252
- * Environment helpers
253
- */
254
- export const helpers = {
255
- isDevelopment: (): boolean => env.NODE_ENV === 'development',
256
- isProduction: (): boolean => env.NODE_ENV === 'production',
257
- isTest: (): boolean => env.NODE_ENV === 'test',
258
-
259
- getServerUrl: (): string => `http://${env.HOST}:${env.PORT}`,
260
- getClientUrl: (): string => `http://${env.HOST}:${env.VITE_PORT}`,
261
-
262
- getDatabaseUrl: (): string | null => {
263
- if (env.DATABASE_URL) return env.DATABASE_URL
264
-
265
- const { DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD } = env
266
- if (DB_HOST && DB_NAME) {
267
- const auth = DB_USER ? `${DB_USER}:${DB_PASSWORD}@` : ''
268
- return `postgres://${auth}${DB_HOST}:${DB_PORT}/${DB_NAME}`
269
- }
270
-
271
- return null
272
- }
273
- }
274
-
275
- /**
276
- * Create namespaced environment access
277
- * @example
278
- * const db = createNamespace('DATABASE_')
279
- * db.get('URL') // reads DATABASE_URL
280
- */
281
- export function createNamespace(prefix: string) {
282
- return {
283
- get: <T>(key: string, defaultValue?: T): T =>
284
- env.get(`${prefix}${key}`, defaultValue),
285
-
286
- has: (key: string): boolean =>
287
- env.has(`${prefix}${key}`),
288
-
289
- all: (): Record<string, string> => {
290
- const allEnv = env.all()
291
- const namespaced: Record<string, string> = {}
292
-
293
- for (const [key, value] of Object.entries(allEnv)) {
294
- if (key.startsWith(prefix)) {
295
- namespaced[key.slice(prefix.length)] = value
296
- }
297
- }
298
-
299
- return namespaced
300
- }
301
- }
302
- }
303
-
304
- // Default export
305
- export default env