create-fluxstack 1.0.0 → 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 (101) hide show
  1. package/create-fluxstack.ts +32 -17
  2. package/package-template.json +51 -0
  3. package/package.json +2 -1
  4. package/.env +0 -30
  5. package/LICENSE +0 -21
  6. package/app/client/README.md +0 -69
  7. package/app/client/frontend-only.ts +0 -12
  8. package/app/client/index.html +0 -13
  9. package/app/client/public/vite.svg +0 -1
  10. package/app/client/src/App.css +0 -883
  11. package/app/client/src/App.tsx +0 -669
  12. package/app/client/src/assets/react.svg +0 -1
  13. package/app/client/src/components/TestPage.tsx +0 -453
  14. package/app/client/src/index.css +0 -51
  15. package/app/client/src/lib/eden-api.ts +0 -110
  16. package/app/client/src/main.tsx +0 -10
  17. package/app/client/src/vite-env.d.ts +0 -1
  18. package/app/client/tsconfig.app.json +0 -43
  19. package/app/client/tsconfig.json +0 -7
  20. package/app/client/tsconfig.node.json +0 -25
  21. package/app/server/app.ts +0 -10
  22. package/app/server/backend-only.ts +0 -15
  23. package/app/server/controllers/users.controller.ts +0 -69
  24. package/app/server/index.ts +0 -104
  25. package/app/server/routes/index.ts +0 -25
  26. package/app/server/routes/users.routes.ts +0 -121
  27. package/app/server/types/index.ts +0 -1
  28. package/app/shared/types/index.ts +0 -18
  29. package/bun.lock +0 -1053
  30. package/core/__tests__/integration.test.ts +0 -227
  31. package/core/build/index.ts +0 -186
  32. package/core/cli/command-registry.ts +0 -334
  33. package/core/cli/index.ts +0 -394
  34. package/core/cli/plugin-discovery.ts +0 -200
  35. package/core/client/standalone.ts +0 -57
  36. package/core/config/__tests__/config-loader.test.ts +0 -591
  37. package/core/config/__tests__/config-merger.test.ts +0 -657
  38. package/core/config/__tests__/env-converter.test.ts +0 -372
  39. package/core/config/__tests__/env-processor.test.ts +0 -431
  40. package/core/config/__tests__/env.test.ts +0 -452
  41. package/core/config/__tests__/integration.test.ts +0 -418
  42. package/core/config/__tests__/loader.test.ts +0 -331
  43. package/core/config/__tests__/schema.test.ts +0 -129
  44. package/core/config/__tests__/validator.test.ts +0 -318
  45. package/core/config/env-dynamic.ts +0 -326
  46. package/core/config/env.ts +0 -597
  47. package/core/config/index.ts +0 -317
  48. package/core/config/loader.ts +0 -546
  49. package/core/config/runtime-config.ts +0 -322
  50. package/core/config/schema.ts +0 -694
  51. package/core/config/validator.ts +0 -540
  52. package/core/framework/__tests__/server.test.ts +0 -233
  53. package/core/framework/client.ts +0 -132
  54. package/core/framework/index.ts +0 -8
  55. package/core/framework/server.ts +0 -501
  56. package/core/framework/types.ts +0 -63
  57. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  58. package/core/plugins/__tests__/manager.test.ts +0 -398
  59. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  60. package/core/plugins/__tests__/registry.test.ts +0 -335
  61. package/core/plugins/built-in/index.ts +0 -142
  62. package/core/plugins/built-in/logger/index.ts +0 -180
  63. package/core/plugins/built-in/monitoring/README.md +0 -193
  64. package/core/plugins/built-in/monitoring/index.ts +0 -912
  65. package/core/plugins/built-in/static/index.ts +0 -289
  66. package/core/plugins/built-in/swagger/index.ts +0 -229
  67. package/core/plugins/built-in/vite/index.ts +0 -316
  68. package/core/plugins/config.ts +0 -348
  69. package/core/plugins/discovery.ts +0 -350
  70. package/core/plugins/executor.ts +0 -351
  71. package/core/plugins/index.ts +0 -195
  72. package/core/plugins/manager.ts +0 -583
  73. package/core/plugins/registry.ts +0 -424
  74. package/core/plugins/types.ts +0 -254
  75. package/core/server/framework.ts +0 -123
  76. package/core/server/index.ts +0 -8
  77. package/core/server/plugins/database.ts +0 -182
  78. package/core/server/plugins/logger.ts +0 -47
  79. package/core/server/plugins/swagger.ts +0 -34
  80. package/core/server/standalone.ts +0 -91
  81. package/core/templates/create-project.ts +0 -455
  82. package/core/types/api.ts +0 -169
  83. package/core/types/build.ts +0 -174
  84. package/core/types/config.ts +0 -68
  85. package/core/types/index.ts +0 -127
  86. package/core/types/plugin.ts +0 -94
  87. package/core/utils/__tests__/errors.test.ts +0 -139
  88. package/core/utils/__tests__/helpers.test.ts +0 -297
  89. package/core/utils/__tests__/logger.test.ts +0 -141
  90. package/core/utils/env-runtime-v2.ts +0 -232
  91. package/core/utils/env-runtime.ts +0 -252
  92. package/core/utils/errors/codes.ts +0 -115
  93. package/core/utils/errors/handlers.ts +0 -63
  94. package/core/utils/errors/index.ts +0 -81
  95. package/core/utils/helpers.ts +0 -180
  96. package/core/utils/index.ts +0 -18
  97. package/core/utils/logger/index.ts +0 -161
  98. package/core/utils/logger.ts +0 -106
  99. package/core/utils/monitoring/index.ts +0 -212
  100. package/tsconfig.json +0 -51
  101. 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
- }