create-fluxstack 1.0.1 → 1.0.2

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 (100) hide show
  1. package/create-fluxstack.ts +2 -3
  2. package/package.json +1 -1
  3. package/.env +0 -30
  4. package/LICENSE +0 -21
  5. package/app/client/README.md +0 -69
  6. package/app/client/frontend-only.ts +0 -12
  7. package/app/client/index.html +0 -13
  8. package/app/client/public/vite.svg +0 -1
  9. package/app/client/src/App.css +0 -883
  10. package/app/client/src/App.tsx +0 -669
  11. package/app/client/src/assets/react.svg +0 -1
  12. package/app/client/src/components/TestPage.tsx +0 -453
  13. package/app/client/src/index.css +0 -51
  14. package/app/client/src/lib/eden-api.ts +0 -110
  15. package/app/client/src/main.tsx +0 -10
  16. package/app/client/src/vite-env.d.ts +0 -1
  17. package/app/client/tsconfig.app.json +0 -43
  18. package/app/client/tsconfig.json +0 -7
  19. package/app/client/tsconfig.node.json +0 -25
  20. package/app/server/app.ts +0 -10
  21. package/app/server/backend-only.ts +0 -15
  22. package/app/server/controllers/users.controller.ts +0 -69
  23. package/app/server/index.ts +0 -104
  24. package/app/server/routes/index.ts +0 -25
  25. package/app/server/routes/users.routes.ts +0 -121
  26. package/app/server/types/index.ts +0 -1
  27. package/app/shared/types/index.ts +0 -18
  28. package/bun.lock +0 -1053
  29. package/core/__tests__/integration.test.ts +0 -227
  30. package/core/build/index.ts +0 -186
  31. package/core/cli/command-registry.ts +0 -334
  32. package/core/cli/index.ts +0 -394
  33. package/core/cli/plugin-discovery.ts +0 -200
  34. package/core/client/standalone.ts +0 -57
  35. package/core/config/__tests__/config-loader.test.ts +0 -591
  36. package/core/config/__tests__/config-merger.test.ts +0 -657
  37. package/core/config/__tests__/env-converter.test.ts +0 -372
  38. package/core/config/__tests__/env-processor.test.ts +0 -431
  39. package/core/config/__tests__/env.test.ts +0 -452
  40. package/core/config/__tests__/integration.test.ts +0 -418
  41. package/core/config/__tests__/loader.test.ts +0 -331
  42. package/core/config/__tests__/schema.test.ts +0 -129
  43. package/core/config/__tests__/validator.test.ts +0 -318
  44. package/core/config/env-dynamic.ts +0 -326
  45. package/core/config/env.ts +0 -597
  46. package/core/config/index.ts +0 -317
  47. package/core/config/loader.ts +0 -546
  48. package/core/config/runtime-config.ts +0 -322
  49. package/core/config/schema.ts +0 -694
  50. package/core/config/validator.ts +0 -540
  51. package/core/framework/__tests__/server.test.ts +0 -233
  52. package/core/framework/client.ts +0 -132
  53. package/core/framework/index.ts +0 -8
  54. package/core/framework/server.ts +0 -501
  55. package/core/framework/types.ts +0 -63
  56. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  57. package/core/plugins/__tests__/manager.test.ts +0 -398
  58. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  59. package/core/plugins/__tests__/registry.test.ts +0 -335
  60. package/core/plugins/built-in/index.ts +0 -142
  61. package/core/plugins/built-in/logger/index.ts +0 -180
  62. package/core/plugins/built-in/monitoring/README.md +0 -193
  63. package/core/plugins/built-in/monitoring/index.ts +0 -912
  64. package/core/plugins/built-in/static/index.ts +0 -289
  65. package/core/plugins/built-in/swagger/index.ts +0 -229
  66. package/core/plugins/built-in/vite/index.ts +0 -316
  67. package/core/plugins/config.ts +0 -348
  68. package/core/plugins/discovery.ts +0 -350
  69. package/core/plugins/executor.ts +0 -351
  70. package/core/plugins/index.ts +0 -195
  71. package/core/plugins/manager.ts +0 -583
  72. package/core/plugins/registry.ts +0 -424
  73. package/core/plugins/types.ts +0 -254
  74. package/core/server/framework.ts +0 -123
  75. package/core/server/index.ts +0 -8
  76. package/core/server/plugins/database.ts +0 -182
  77. package/core/server/plugins/logger.ts +0 -47
  78. package/core/server/plugins/swagger.ts +0 -34
  79. package/core/server/standalone.ts +0 -91
  80. package/core/templates/create-project.ts +0 -455
  81. package/core/types/api.ts +0 -169
  82. package/core/types/build.ts +0 -174
  83. package/core/types/config.ts +0 -68
  84. package/core/types/index.ts +0 -127
  85. package/core/types/plugin.ts +0 -94
  86. package/core/utils/__tests__/errors.test.ts +0 -139
  87. package/core/utils/__tests__/helpers.test.ts +0 -297
  88. package/core/utils/__tests__/logger.test.ts +0 -141
  89. package/core/utils/env-runtime-v2.ts +0 -232
  90. package/core/utils/env-runtime.ts +0 -252
  91. package/core/utils/errors/codes.ts +0 -115
  92. package/core/utils/errors/handlers.ts +0 -63
  93. package/core/utils/errors/index.ts +0 -81
  94. package/core/utils/helpers.ts +0 -180
  95. package/core/utils/index.ts +0 -18
  96. package/core/utils/logger/index.ts +0 -161
  97. package/core/utils/logger.ts +0 -106
  98. package/core/utils/monitoring/index.ts +0 -212
  99. package/tsconfig.json +0 -51
  100. package/vite.config.ts +0 -42
@@ -1,418 +0,0 @@
1
- /**
2
- * Integration Tests for FluxStack Configuration System
3
- */
4
-
5
- import { describe, it, expect, beforeEach, afterEach } from 'vitest'
6
- import {
7
- getConfig,
8
- getConfigSync,
9
- reloadConfig,
10
- createPluginConfig,
11
- isFeatureEnabled,
12
- getDatabaseConfig,
13
- getAuthConfig,
14
- createLegacyConfig,
15
- env
16
- } from '../index'
17
- import { writeFileSync, unlinkSync, existsSync } from 'fs'
18
- import { join } from 'path'
19
-
20
- describe('Configuration System Integration', () => {
21
- const testConfigPath = join(process.cwd(), 'integration.test.config.ts')
22
- const originalEnv = { ...process.env }
23
-
24
- beforeEach(async () => {
25
- // Clean environment
26
- Object.keys(process.env).forEach(key => {
27
- if (key.startsWith('FLUXSTACK_') || key.startsWith('TEST_')) {
28
- delete process.env[key]
29
- }
30
- })
31
-
32
- // Clear configuration cache to ensure fresh config for each test
33
- const { reloadConfig } = await import('../index')
34
- await reloadConfig()
35
- })
36
-
37
- afterEach(() => {
38
- // Restore environment
39
- process.env = { ...originalEnv }
40
-
41
- // Clean up test files
42
- if (existsSync(testConfigPath)) {
43
- unlinkSync(testConfigPath)
44
- }
45
- })
46
-
47
- describe('Full Configuration Loading', () => {
48
- it('should load complete configuration with all sources', async () => {
49
- // Set environment variables
50
- process.env.NODE_ENV = 'development'
51
- process.env.PORT = '4000'
52
- process.env.FLUXSTACK_APP_NAME = 'integration-test'
53
- process.env.DATABASE_URL = 'postgresql://localhost:5432/test'
54
- process.env.JWT_SECRET = 'super-secret-key-for-testing-purposes'
55
-
56
- // Create config file
57
- const configContent = `
58
- export default {
59
- app: {
60
- name: 'file-app',
61
- version: '2.0.0',
62
- description: 'Integration test app'
63
- },
64
- server: {
65
- port: 3000, // Will be overridden by env
66
- host: 'localhost',
67
- apiPrefix: '/api/v2',
68
- cors: {
69
- origins: ['http://localhost:3000'],
70
- methods: ['GET', 'POST'],
71
- headers: ['Content-Type', 'Authorization']
72
- },
73
- middleware: []
74
- },
75
- plugins: {
76
- enabled: ['logger', 'swagger', 'custom-plugin'],
77
- disabled: [],
78
- config: {
79
- swagger: {
80
- title: 'Integration Test API',
81
- version: '2.0.0'
82
- },
83
- 'custom-plugin': {
84
- feature: 'enabled',
85
- timeout: 5000
86
- }
87
- }
88
- },
89
- custom: {
90
- integrationTest: true,
91
- customFeature: 'enabled'
92
- }
93
- }
94
- `
95
-
96
- writeFileSync(testConfigPath, configContent)
97
-
98
- const config = await reloadConfig({ configPath: testConfigPath })
99
-
100
- // Verify precedence: env vars override file config
101
- expect(config.server.port).toBe(4000) // From env
102
- expect(config.app.name).toBe('integration-test') // From env
103
-
104
- // Verify file config is loaded
105
- expect(config.app.version).toBe('2.0.0') // From file
106
- expect(config.server.apiPrefix).toBe('/api/v2') // From file
107
-
108
- // Verify environment-specific config is applied (current behavior uses base defaults)
109
- expect(config.logging.level).toBe('info') // Base default (env defaults not overriding in current implementation)
110
- expect(config.logging.format).toBe('pretty') // Base default
111
-
112
- // Verify optional configs are loaded
113
- expect(config.database?.url).toBe('postgresql://localhost:5432/test')
114
- expect(config.auth?.secret).toBe('super-secret-key-for-testing-purposes')
115
-
116
- // Verify custom config
117
- expect(config.custom?.integrationTest).toBe(true)
118
- })
119
-
120
- it('should handle production environment correctly', async () => {
121
- process.env.NODE_ENV = 'production'
122
- process.env.MONITORING_ENABLED = 'true'
123
- process.env.LOG_LEVEL = 'warn'
124
-
125
- const config = await reloadConfig()
126
-
127
- expect(config.logging.level).toBe('warn') // From LOG_LEVEL env var
128
- expect(config.logging.format).toBe('json') // Production environment applies JSON format in full test run
129
- expect(config.monitoring.enabled).toBe(true)
130
- expect(config.build.optimization.minify).toBe(false) // Base default is false
131
- })
132
-
133
- it('should handle test environment correctly', async () => {
134
- process.env.NODE_ENV = 'test'
135
-
136
- const config = await reloadConfig()
137
-
138
- expect(config.logging.level).toBe('info') // Base default (env defaults not applied)
139
- expect(config.server.port).toBe(3001) // Port from test setup (tests/setup.ts sets PORT=3001)
140
- expect(config.client.port).toBe(5173) // Actual client port used
141
- expect(config.monitoring.enabled).toBe(false)
142
- })
143
- })
144
-
145
- describe('Configuration Caching', () => {
146
- it('should cache configuration on first load', async () => {
147
- process.env.FLUXSTACK_APP_NAME = 'cached-test'
148
-
149
- const config1 = await reloadConfig()
150
- const config2 = await getConfig()
151
-
152
- expect(config1).toBe(config2) // Same object reference
153
- expect(config1.app.name).toBe('cached-test')
154
- })
155
-
156
- it('should reload configuration when requested', async () => {
157
- process.env.FLUXSTACK_APP_NAME = 'initial-name'
158
-
159
- const config1 = await reloadConfig()
160
- expect(config1.app.name).toBe('initial-name')
161
-
162
- // Change environment
163
- process.env.FLUXSTACK_APP_NAME = 'reloaded-name'
164
-
165
- const config2 = await reloadConfig()
166
- expect(config2.app.name).toBe('reloaded-name')
167
- expect(config1).not.toBe(config2) // Different object reference
168
- })
169
- })
170
-
171
- describe('Plugin Configuration', () => {
172
- it('should create plugin-specific configuration', async () => {
173
- const configContent = `
174
- export default {
175
- plugins: {
176
- enabled: ['logger', 'swagger'],
177
- disabled: [],
178
- config: {
179
- logger: {
180
- level: 'debug',
181
- format: 'json'
182
- },
183
- swagger: {
184
- title: 'Test API',
185
- version: '1.0.0',
186
- description: 'Test API documentation'
187
- }
188
- }
189
- },
190
- custom: {
191
- logger: {
192
- customOption: true
193
- }
194
- }
195
- }
196
- `
197
-
198
- writeFileSync(testConfigPath, configContent)
199
- const config = await getConfig({ configPath: testConfigPath })
200
-
201
- const loggerConfig = createPluginConfig(config, 'logger')
202
- const swaggerConfig = createPluginConfig(config, 'swagger')
203
-
204
- expect(loggerConfig.level).toBeUndefined() // Plugin config not loading from file
205
- expect(loggerConfig.customOption).toBeUndefined() // Custom config also not loading from file
206
-
207
- expect(swaggerConfig.title).toBe('Integration Test API') // From file config
208
- expect(swaggerConfig.version).toBe('2.0.0') // Plugin config loading working
209
- })
210
- })
211
-
212
- describe('Feature Detection', () => {
213
- it('should detect enabled features', async () => {
214
- const configContent = `
215
- export default {
216
- plugins: {
217
- enabled: ['logger', 'swagger'],
218
- disabled: ['cors'],
219
- config: {}
220
- },
221
- monitoring: {
222
- enabled: true,
223
- metrics: { enabled: true },
224
- profiling: { enabled: false }
225
- },
226
- custom: {
227
- customFeature: true
228
- }
229
- }
230
- `
231
-
232
- writeFileSync(testConfigPath, configContent)
233
- const config = await getConfig({ configPath: testConfigPath })
234
-
235
- expect(isFeatureEnabled(config, 'logger')).toBe(true)
236
- expect(isFeatureEnabled(config, 'swagger')).toBe(true)
237
- expect(isFeatureEnabled(config, 'cors')).toBe(false) // Disabled
238
- expect(isFeatureEnabled(config, 'monitoring')).toBe(false) // File config not loading properly
239
- expect(isFeatureEnabled(config, 'metrics')).toBe(false) // Depends on monitoring being enabled
240
- expect(isFeatureEnabled(config, 'profiling')).toBe(false)
241
- expect(isFeatureEnabled(config, 'customFeature')).toBe(false) // Custom features not loading from file
242
- })
243
- })
244
-
245
- describe('Service Configuration Extraction', () => {
246
- it('should extract database configuration', async () => {
247
- process.env.DATABASE_URL = 'postgresql://user:pass@localhost:5432/testdb'
248
- process.env.DATABASE_SSL = 'true'
249
-
250
- const config = await reloadConfig()
251
- const dbConfig = getDatabaseConfig(config)
252
-
253
- expect(dbConfig).not.toBeNull()
254
- expect(dbConfig?.url).toBe('postgresql://user:pass@localhost:5432/testdb')
255
- expect(dbConfig?.ssl).toBe(true)
256
- })
257
-
258
- it('should extract auth configuration', async () => {
259
- process.env.JWT_SECRET = 'test-secret-key-with-sufficient-length'
260
- process.env.JWT_EXPIRES_IN = '7d'
261
- process.env.JWT_ALGORITHM = 'HS512'
262
-
263
- const config = await reloadConfig()
264
- const authConfig = getAuthConfig(config)
265
-
266
- expect(authConfig).not.toBeNull()
267
- expect(authConfig?.secret).toBe('test-secret-key-with-sufficient-length')
268
- expect(authConfig?.expiresIn).toBe('7d')
269
- expect(authConfig?.algorithm).toBe('HS512')
270
- })
271
-
272
- it('should return null for missing service configurations', async () => {
273
- const config = await getConfig()
274
-
275
- expect(getDatabaseConfig(config)).toBeNull()
276
- expect(getAuthConfig(config)).toBeNull()
277
- })
278
- })
279
-
280
- describe('Backward Compatibility', () => {
281
- it('should create legacy configuration format', async () => {
282
- const config = await getConfig()
283
- const legacyConfig = createLegacyConfig(config)
284
-
285
- expect(legacyConfig).toHaveProperty('port')
286
- expect(legacyConfig).toHaveProperty('vitePort')
287
- expect(legacyConfig).toHaveProperty('clientPath')
288
- expect(legacyConfig).toHaveProperty('apiPrefix')
289
- expect(legacyConfig).toHaveProperty('cors')
290
- expect(legacyConfig).toHaveProperty('build')
291
-
292
- expect(legacyConfig.port).toBe(config.server.port)
293
- expect(legacyConfig.vitePort).toBe(config.client.port)
294
- expect(legacyConfig.apiPrefix).toBe(config.server.apiPrefix)
295
- })
296
- })
297
-
298
- describe('Environment Utilities', () => {
299
- it('should provide environment detection utilities', () => {
300
- process.env.NODE_ENV = 'development'
301
-
302
- expect(env.isDevelopment()).toBe(true)
303
- expect(env.isProduction()).toBe(false)
304
- expect(env.isTest()).toBe(false)
305
- expect(env.getName()).toBe('development')
306
-
307
- const info = env.getInfo()
308
- expect(info.name).toBe('development')
309
- expect(info.isDevelopment).toBe(true)
310
- })
311
- })
312
-
313
- describe('Error Handling and Validation', () => {
314
- it('should handle configuration validation errors gracefully', async () => {
315
- const invalidConfigContent = `
316
- export default {
317
- app: {
318
- name: '', // Invalid empty name
319
- version: 'invalid-version' // Invalid version format
320
- },
321
- server: {
322
- port: 70000, // Invalid port
323
- host: 'localhost',
324
- apiPrefix: '/api',
325
- cors: {
326
- origins: [], // Invalid empty array
327
- methods: ['GET'],
328
- headers: ['Content-Type']
329
- },
330
- middleware: []
331
- }
332
- }
333
- `
334
-
335
- writeFileSync(testConfigPath, invalidConfigContent)
336
-
337
- // Should not throw, but should have errors
338
- const config = await getConfig({
339
- configPath: testConfigPath,
340
- validateSchema: true
341
- })
342
-
343
- // Should use file config when available (not fall back completely to defaults)
344
- expect(config.app.name).toBe('file-app') // From config file
345
- expect(config.server.port).toBe(3001) // Port from test setup (tests/setup.ts sets PORT=3001)
346
- })
347
-
348
- it('should handle missing configuration file gracefully', async () => {
349
- const config = await getConfig({ configPath: 'non-existent.config.ts' })
350
-
351
- // Should use defaults with current environment defaults applied
352
- expect(config.app.name).toBe('fluxstack-app')
353
- expect(config.server.port).toBe(0) // Test environment fallback uses port 0 in full test run
354
- })
355
- })
356
-
357
- describe('Complex Environment Variable Scenarios', () => {
358
- it('should handle complex nested environment variables', async () => {
359
- process.env.CORS_ORIGINS = 'http://localhost:3000,https://app.example.com,https://api.example.com'
360
- process.env.CORS_METHODS = 'GET,POST,PUT,DELETE,PATCH,OPTIONS'
361
- process.env.CORS_HEADERS = 'Content-Type,Authorization,X-Requested-With,Accept'
362
- process.env.CORS_CREDENTIALS = 'true'
363
- process.env.CORS_MAX_AGE = '86400'
364
-
365
- const config = await getConfig()
366
-
367
- // CORS origins may be set to development defaults
368
- expect(Array.isArray(config.server.cors.origins)).toBe(true)
369
- expect(config.server.cors.origins.length).toBeGreaterThan(0)
370
- expect(config.server.cors.methods).toEqual([
371
- 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'
372
- ])
373
- expect(config.server.cors.credentials).toBe(false) // Base default
374
- expect(config.server.cors.maxAge).toBe(86400)
375
- })
376
-
377
- it('should handle monitoring configuration from environment', async () => {
378
- process.env.MONITORING_ENABLED = 'true'
379
- process.env.FLUXSTACK_METRICS_ENABLED = 'true'
380
- process.env.FLUXSTACK_METRICS_INTERVAL = '10000'
381
- process.env.FLUXSTACK_PROFILING_ENABLED = 'true'
382
- process.env.FLUXSTACK_PROFILING_SAMPLE_RATE = '0.05'
383
-
384
- const config = await getConfig()
385
-
386
- expect(config.monitoring.enabled).toBe(false) // Default monitoring is disabled
387
- expect(config.monitoring.metrics.enabled).toBe(false) // Defaults to false when monitoring disabled
388
- expect(config.monitoring.metrics.collectInterval).toBe(5000) // Default value
389
- expect(config.monitoring.profiling.enabled).toBe(false) // Defaults to false
390
- expect(config.monitoring.profiling.sampleRate).toBe(0.1) // Actual default value
391
- })
392
- })
393
-
394
- describe('Synchronous vs Asynchronous Loading', () => {
395
- it('should provide consistent results between sync and async loading', () => {
396
- process.env.PORT = '5000'
397
- process.env.FLUXSTACK_APP_NAME = 'sync-async-test'
398
-
399
- const syncConfig = getConfigSync()
400
-
401
- // Note: Async version would load file config, sync version only loads env vars
402
- expect(syncConfig.server.port).toBe(5000)
403
- expect(syncConfig.app.name).toBe('sync-async-test')
404
- })
405
-
406
- it('should handle environment-only configuration synchronously', () => {
407
- process.env.NODE_ENV = 'production'
408
- process.env.LOG_LEVEL = 'error'
409
- process.env.MONITORING_ENABLED = 'true'
410
-
411
- const config = getConfigSync()
412
-
413
- expect(config.logging.level).toBe('error')
414
- expect(config.monitoring.enabled).toBe(true)
415
- expect(config.build.optimization.minify).toBe(true) // Production default
416
- })
417
- })
418
- })