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,540 +0,0 @@
1
- /**
2
- * Configuration Validation System for FluxStack
3
- * Provides comprehensive validation with detailed error reporting
4
- */
5
-
6
- import type { FluxStackConfig } from './schema'
7
- import { fluxStackConfigSchema } from './schema'
8
-
9
- export interface ValidationError {
10
- path: string
11
- message: string
12
- value?: any
13
- expected?: string
14
- }
15
-
16
- export interface ValidationWarning {
17
- path: string
18
- message: string
19
- suggestion?: string
20
- }
21
-
22
- export interface ValidationResult {
23
- valid: boolean
24
- errors: string[]
25
- warnings: string[]
26
- details: {
27
- errors: ValidationError[]
28
- warnings: ValidationWarning[]
29
- }
30
- }
31
-
32
- /**
33
- * JSON Schema validator implementation
34
- */
35
- class SchemaValidator {
36
- private validateProperty(
37
- value: any,
38
- schema: any,
39
- path: string = '',
40
- errors: ValidationError[] = [],
41
- warnings: ValidationWarning[] = []
42
- ): void {
43
- if (schema.type) {
44
- this.validateType(value, schema, path, errors)
45
- }
46
-
47
- if (schema.properties && typeof value === 'object' && value !== null) {
48
- this.validateObject(value, schema, path, errors, warnings)
49
- }
50
-
51
- if (schema.items && Array.isArray(value)) {
52
- this.validateArray(value, schema, path, errors, warnings)
53
- }
54
-
55
- if (schema.enum) {
56
- this.validateEnum(value, schema, path, errors)
57
- }
58
-
59
- if (schema.pattern && typeof value === 'string') {
60
- this.validatePattern(value, schema, path, errors)
61
- }
62
-
63
- if (schema.minimum !== undefined && typeof value === 'number') {
64
- this.validateMinimum(value, schema, path, errors)
65
- }
66
-
67
- if (schema.maximum !== undefined && typeof value === 'number') {
68
- this.validateMaximum(value, schema, path, errors)
69
- }
70
-
71
- if (schema.minLength !== undefined && typeof value === 'string') {
72
- this.validateMinLength(value, schema, path, errors)
73
- }
74
-
75
- if (schema.maxLength !== undefined && typeof value === 'string') {
76
- this.validateMaxLength(value, schema, path, errors)
77
- }
78
-
79
- if (schema.minItems !== undefined && Array.isArray(value)) {
80
- this.validateMinItems(value, schema, path, errors)
81
- }
82
- }
83
-
84
- private validateType(value: any, schema: any, path: string, errors: ValidationError[]): void {
85
- const actualType = Array.isArray(value) ? 'array' : typeof value
86
- const expectedType = schema.type
87
-
88
- if (actualType !== expectedType) {
89
- errors.push({
90
- path,
91
- message: `Expected ${expectedType}, got ${actualType}`,
92
- value,
93
- expected: expectedType
94
- })
95
- }
96
- }
97
-
98
- private validateObject(
99
- value: any,
100
- schema: any,
101
- path: string,
102
- errors: ValidationError[],
103
- warnings: ValidationWarning[]
104
- ): void {
105
- // Check required properties
106
- if (schema.required) {
107
- for (const requiredProp of schema.required) {
108
- if (!(requiredProp in value)) {
109
- errors.push({
110
- path: path ? `${path}.${requiredProp}` : requiredProp,
111
- message: `Missing required property '${requiredProp}'`,
112
- expected: 'required property'
113
- })
114
- }
115
- }
116
- }
117
-
118
- // Validate existing properties
119
- for (const [key, propValue] of Object.entries(value)) {
120
- const propPath = path ? `${path}.${key}` : key
121
- const propSchema = schema.properties?.[key]
122
-
123
- if (propSchema) {
124
- this.validateProperty(propValue, propSchema, propPath, errors, warnings)
125
- } else if (schema.additionalProperties === false) {
126
- warnings.push({
127
- path: propPath,
128
- message: `Unknown property '${key}'`,
129
- suggestion: 'Remove this property or add it to the schema'
130
- })
131
- }
132
- }
133
- }
134
-
135
- private validateArray(
136
- value: any[],
137
- schema: any,
138
- path: string,
139
- errors: ValidationError[],
140
- warnings: ValidationWarning[]
141
- ): void {
142
- value.forEach((item, index) => {
143
- const itemPath = `${path}[${index}]`
144
- this.validateProperty(item, schema.items, itemPath, errors, warnings)
145
- })
146
- }
147
-
148
- private validateEnum(value: any, schema: any, path: string, errors: ValidationError[]): void {
149
- if (!schema.enum.includes(value)) {
150
- errors.push({
151
- path,
152
- message: `Value must be one of: ${schema.enum.join(', ')}`,
153
- value,
154
- expected: schema.enum.join(' | ')
155
- })
156
- }
157
- }
158
-
159
- private validatePattern(value: string, schema: any, path: string, errors: ValidationError[]): void {
160
- const regex = new RegExp(schema.pattern)
161
- if (!regex.test(value)) {
162
- errors.push({
163
- path,
164
- message: `Value does not match pattern: ${schema.pattern}`,
165
- value,
166
- expected: `pattern: ${schema.pattern}`
167
- })
168
- }
169
- }
170
-
171
- private validateMinimum(value: number, schema: any, path: string, errors: ValidationError[]): void {
172
- if (value < schema.minimum) {
173
- errors.push({
174
- path,
175
- message: `Value must be >= ${schema.minimum}`,
176
- value,
177
- expected: `>= ${schema.minimum}`
178
- })
179
- }
180
- }
181
-
182
- private validateMaximum(value: number, schema: any, path: string, errors: ValidationError[]): void {
183
- if (value > schema.maximum) {
184
- errors.push({
185
- path,
186
- message: `Value must be <= ${schema.maximum}`,
187
- value,
188
- expected: `<= ${schema.maximum}`
189
- })
190
- }
191
- }
192
-
193
- private validateMinLength(value: string, schema: any, path: string, errors: ValidationError[]): void {
194
- if (value.length < schema.minLength) {
195
- errors.push({
196
- path,
197
- message: `String must be at least ${schema.minLength} characters long`,
198
- value,
199
- expected: `length >= ${schema.minLength}`
200
- })
201
- }
202
- }
203
-
204
- private validateMaxLength(value: string, schema: any, path: string, errors: ValidationError[]): void {
205
- if (value.length > schema.maxLength) {
206
- errors.push({
207
- path,
208
- message: `String must be at most ${schema.maxLength} characters long`,
209
- value,
210
- expected: `length <= ${schema.maxLength}`
211
- })
212
- }
213
- }
214
-
215
- private validateMinItems(value: any[], schema: any, path: string, errors: ValidationError[]): void {
216
- if (value.length < schema.minItems) {
217
- errors.push({
218
- path,
219
- message: `Array must have at least ${schema.minItems} items`,
220
- value,
221
- expected: `length >= ${schema.minItems}`
222
- })
223
- }
224
- }
225
-
226
- validate(value: any, schema: any): ValidationResult {
227
- const errors: ValidationError[] = []
228
- const warnings: ValidationWarning[] = []
229
-
230
- this.validateProperty(value, schema, '', errors, warnings)
231
-
232
- return {
233
- valid: errors.length === 0,
234
- errors: errors.map(e => `${e.path}: ${e.message}`),
235
- warnings: warnings.map(w => `${w.path}: ${w.message}${w.suggestion ? ` (${w.suggestion})` : ''}`),
236
- details: { errors, warnings }
237
- }
238
- }
239
- }
240
-
241
- /**
242
- * Business logic validation rules
243
- */
244
- class BusinessValidator {
245
- validate(config: FluxStackConfig): ValidationResult {
246
- const errors: ValidationError[] = []
247
- const warnings: ValidationWarning[] = []
248
-
249
- // Port conflict validation
250
- this.validatePortConflicts(config, errors)
251
-
252
- // CORS validation
253
- this.validateCorsConfiguration(config, warnings)
254
-
255
- // Plugin validation
256
- this.validatePluginConfiguration(config, warnings)
257
-
258
- // Build configuration validation
259
- this.validateBuildConfiguration(config, warnings)
260
-
261
- // Environment-specific validation
262
- this.validateEnvironmentConfiguration(config, warnings)
263
-
264
- // Security validation
265
- this.validateSecurityConfiguration(config, warnings)
266
-
267
- return {
268
- valid: errors.length === 0,
269
- errors: errors.map(e => `${e.path}: ${e.message}`),
270
- warnings: warnings.map(w => `${w.path}: ${w.message}${w.suggestion ? ` (${w.suggestion})` : ''}`),
271
- details: { errors, warnings }
272
- }
273
- }
274
-
275
- private validatePortConflicts(config: FluxStackConfig, errors: ValidationError[]): void {
276
- const ports = [config.server.port, config.client.port]
277
- const uniquePorts = new Set(ports.filter(p => p !== 0)) // 0 means random port
278
-
279
- if (uniquePorts.size !== ports.filter(p => p !== 0).length) {
280
- errors.push({
281
- path: 'ports',
282
- message: 'Server and client ports must be different',
283
- value: { server: config.server.port, client: config.client.port }
284
- })
285
- }
286
- }
287
-
288
- private validateCorsConfiguration(config: FluxStackConfig, warnings: ValidationWarning[]): void {
289
- const { cors } = config.server
290
-
291
- // Check for overly permissive CORS
292
- if (cors.origins.includes('*')) {
293
- warnings.push({
294
- path: 'server.cors.origins',
295
- message: 'Using wildcard (*) for CORS origins is not recommended in production',
296
- suggestion: 'Specify explicit origins for better security'
297
- })
298
- }
299
-
300
- // Check for missing common headers
301
- const commonHeaders = ['Content-Type', 'Authorization']
302
- const missingHeaders = commonHeaders.filter(h => !cors.headers.includes(h))
303
-
304
- if (missingHeaders.length > 0) {
305
- warnings.push({
306
- path: 'server.cors.headers',
307
- message: `Consider adding common headers: ${missingHeaders.join(', ')}`,
308
- suggestion: 'These headers are commonly needed for API requests'
309
- })
310
- }
311
- }
312
-
313
- private validatePluginConfiguration(config: FluxStackConfig, warnings: ValidationWarning[]): void {
314
- const { enabled, disabled } = config.plugins
315
-
316
- // Check for plugins in both enabled and disabled lists
317
- const conflicts = enabled.filter(p => disabled.includes(p))
318
- if (conflicts.length > 0) {
319
- warnings.push({
320
- path: 'plugins',
321
- message: `Plugins listed in both enabled and disabled: ${conflicts.join(', ')}`,
322
- suggestion: 'Remove from one of the lists'
323
- })
324
- }
325
-
326
- // Check for essential plugins
327
- const essentialPlugins = ['logger', 'cors']
328
- const missingEssential = essentialPlugins.filter(p =>
329
- !enabled.includes(p) || disabled.includes(p)
330
- )
331
-
332
- if (missingEssential.length > 0) {
333
- warnings.push({
334
- path: 'plugins.enabled',
335
- message: `Consider enabling essential plugins: ${missingEssential.join(', ')}`,
336
- suggestion: 'These plugins provide important functionality'
337
- })
338
- }
339
- }
340
-
341
- private validateBuildConfiguration(config: FluxStackConfig, warnings: ValidationWarning[]): void {
342
- const { build } = config
343
-
344
- // Check for development settings in production
345
- if (process.env.NODE_ENV === 'production') {
346
- if (!build.optimization.minify) {
347
- warnings.push({
348
- path: 'build.optimization.minify',
349
- message: 'Minification is disabled in production',
350
- suggestion: 'Enable minification for better performance'
351
- })
352
- }
353
-
354
- if (!build.optimization.treeshake) {
355
- warnings.push({
356
- path: 'build.optimization.treeshake',
357
- message: 'Tree-shaking is disabled in production',
358
- suggestion: 'Enable tree-shaking to reduce bundle size'
359
- })
360
- }
361
- }
362
-
363
- // Check for conflicting settings
364
- if (build.optimization.bundleAnalyzer && process.env.NODE_ENV === 'production') {
365
- warnings.push({
366
- path: 'build.optimization.bundleAnalyzer',
367
- message: 'Bundle analyzer is enabled in production',
368
- suggestion: 'Disable bundle analyzer in production builds'
369
- })
370
- }
371
- }
372
-
373
- private validateEnvironmentConfiguration(config: FluxStackConfig, warnings: ValidationWarning[]): void {
374
- if (config.environments) {
375
- for (const [env, envConfig] of Object.entries(config.environments)) {
376
- if (envConfig && typeof envConfig === 'object') {
377
- // Check for potentially dangerous overrides
378
- if ('server' in envConfig && envConfig.server && 'port' in envConfig.server) {
379
- if (envConfig.server.port === 0 && env !== 'test') {
380
- warnings.push({
381
- path: `environments.${env}.server.port`,
382
- message: 'Using random port (0) in non-test environment',
383
- suggestion: 'Specify a fixed port for predictable deployments'
384
- })
385
- }
386
- }
387
- }
388
- }
389
- }
390
- }
391
-
392
- private validateSecurityConfiguration(config: FluxStackConfig, warnings: ValidationWarning[]): void {
393
- // Check for missing authentication configuration in production
394
- if (process.env.NODE_ENV === 'production' && !config.auth?.secret) {
395
- warnings.push({
396
- path: 'auth.secret',
397
- message: 'No authentication secret configured for production',
398
- suggestion: 'Set JWT_SECRET environment variable for secure authentication'
399
- })
400
- }
401
-
402
- // Check for weak authentication settings
403
- if (config.auth?.secret && config.auth.secret.length < 32) {
404
- warnings.push({
405
- path: 'auth.secret',
406
- message: 'Authentication secret is too short',
407
- suggestion: 'Use at least 32 characters for better security'
408
- })
409
- }
410
-
411
- // Check for insecure CORS in production
412
- if (process.env.NODE_ENV === 'production' && config.server.cors.credentials) {
413
- const hasWildcard = config.server.cors.origins.includes('*')
414
- if (hasWildcard) {
415
- warnings.push({
416
- path: 'server.cors',
417
- message: 'CORS credentials enabled with wildcard origins in production',
418
- suggestion: 'Specify explicit origins when using credentials'
419
- })
420
- }
421
- }
422
- }
423
- }
424
-
425
- /**
426
- * Main configuration validator
427
- */
428
- export function validateConfig(config: FluxStackConfig): ValidationResult {
429
- const schemaValidator = new SchemaValidator()
430
- const businessValidator = new BusinessValidator()
431
-
432
- // Validate against JSON schema
433
- const schemaResult = schemaValidator.validate(config, fluxStackConfigSchema)
434
-
435
- // Validate business rules
436
- const businessResult = businessValidator.validate(config)
437
-
438
- // Combine results
439
- return {
440
- valid: schemaResult.valid && businessResult.valid,
441
- errors: [...schemaResult.errors, ...businessResult.errors],
442
- warnings: [...schemaResult.warnings, ...businessResult.warnings],
443
- details: {
444
- errors: [...schemaResult.details.errors, ...businessResult.details.errors],
445
- warnings: [...schemaResult.details.warnings, ...businessResult.details.warnings]
446
- }
447
- }
448
- }
449
-
450
- /**
451
- * Validate configuration and throw on errors
452
- */
453
- export function validateConfigStrict(config: FluxStackConfig): void {
454
- const result = validateConfig(config)
455
-
456
- if (!result.valid) {
457
- const errorMessage = [
458
- 'Configuration validation failed:',
459
- ...result.errors.map(e => ` - ${e}`),
460
- ...(result.warnings.length > 0 ? ['Warnings:', ...result.warnings.map(w => ` - ${w}`)] : [])
461
- ].join('\n')
462
-
463
- throw new Error(errorMessage)
464
- }
465
- }
466
-
467
- /**
468
- * Create a configuration validator for a specific environment
469
- */
470
- export function createEnvironmentValidator(environment: string) {
471
- return (config: FluxStackConfig): ValidationResult => {
472
- // Apply environment-specific validation rules
473
- const result = validateConfig(config)
474
-
475
- // Add environment-specific warnings/errors
476
- if (environment === 'production') {
477
- // Additional production validations
478
- if (config.logging.level === 'debug') {
479
- result.warnings.push('Debug logging enabled in production - consider using "warn" or "error"')
480
- }
481
-
482
- if (!config.monitoring.enabled) {
483
- result.warnings.push('Monitoring is disabled in production - consider enabling for better observability')
484
- }
485
- }
486
-
487
- if (environment === 'development') {
488
- // Additional development validations
489
- if (config.build.optimization.minify) {
490
- result.warnings.push('Minification enabled in development - this may slow down builds')
491
- }
492
- }
493
-
494
- return result
495
- }
496
- }
497
-
498
- /**
499
- * Validate partial configuration (useful for updates)
500
- */
501
- export function validatePartialConfig(
502
- partialConfig: Partial<FluxStackConfig>,
503
- baseConfig: FluxStackConfig
504
- ): ValidationResult {
505
- // Merge partial config with base config
506
- const mergedConfig = { ...baseConfig, ...partialConfig }
507
-
508
- // Validate the merged configuration
509
- return validateConfig(mergedConfig)
510
- }
511
-
512
- /**
513
- * Get validation suggestions for improving configuration
514
- */
515
- export function getConfigSuggestions(config: FluxStackConfig): string[] {
516
- const result = validateConfig(config)
517
- const suggestions: string[] = []
518
-
519
- // Extract suggestions from warnings
520
- for (const warning of result.details.warnings) {
521
- if (warning.suggestion) {
522
- suggestions.push(`${warning.path}: ${warning.suggestion}`)
523
- }
524
- }
525
-
526
- // Add general suggestions based on configuration
527
- if (!config.monitoring.enabled) {
528
- suggestions.push('Consider enabling monitoring for better observability')
529
- }
530
-
531
- if (config.plugins.enabled.length === 0) {
532
- suggestions.push('Consider enabling some plugins to extend functionality')
533
- }
534
-
535
- if (!config.database && !config.custom?.database) {
536
- suggestions.push('Consider adding database configuration if your app needs persistence')
537
- }
538
-
539
- return suggestions
540
- }