create-fluxstack 1.10.1 → 1.12.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 (257) hide show
  1. package/.dockerignore +1 -2
  2. package/Dockerfile +8 -8
  3. package/LLMD/INDEX.md +64 -0
  4. package/LLMD/MAINTENANCE.md +197 -0
  5. package/LLMD/MIGRATION.md +156 -0
  6. package/LLMD/config/.gitkeep +1 -0
  7. package/LLMD/config/declarative-system.md +268 -0
  8. package/LLMD/config/environment-vars.md +327 -0
  9. package/LLMD/config/runtime-reload.md +401 -0
  10. package/LLMD/core/.gitkeep +1 -0
  11. package/LLMD/core/build-system.md +599 -0
  12. package/LLMD/core/framework-lifecycle.md +229 -0
  13. package/LLMD/core/plugin-system.md +451 -0
  14. package/LLMD/patterns/.gitkeep +1 -0
  15. package/LLMD/patterns/anti-patterns.md +297 -0
  16. package/LLMD/patterns/project-structure.md +264 -0
  17. package/LLMD/patterns/type-safety.md +440 -0
  18. package/LLMD/reference/.gitkeep +1 -0
  19. package/LLMD/reference/cli-commands.md +250 -0
  20. package/LLMD/reference/plugin-hooks.md +357 -0
  21. package/LLMD/reference/routing.md +39 -0
  22. package/LLMD/reference/troubleshooting.md +364 -0
  23. package/LLMD/resources/.gitkeep +1 -0
  24. package/LLMD/resources/controllers.md +465 -0
  25. package/LLMD/resources/live-components.md +703 -0
  26. package/LLMD/resources/live-rooms.md +482 -0
  27. package/LLMD/resources/live-upload.md +130 -0
  28. package/LLMD/resources/plugins-external.md +617 -0
  29. package/LLMD/resources/routes-eden.md +254 -0
  30. package/README.md +37 -17
  31. package/app/client/index.html +0 -1
  32. package/app/client/src/App.tsx +107 -150
  33. package/app/client/src/components/AppLayout.tsx +68 -0
  34. package/app/client/src/components/BackButton.tsx +13 -0
  35. package/app/client/src/components/DemoPage.tsx +20 -0
  36. package/app/client/src/components/LiveUploadWidget.tsx +204 -0
  37. package/app/client/src/lib/eden-api.ts +85 -60
  38. package/app/client/src/live/ChatDemo.tsx +107 -0
  39. package/app/client/src/live/CounterDemo.tsx +206 -0
  40. package/app/client/src/live/FormDemo.tsx +119 -0
  41. package/app/client/src/live/RoomChatDemo.tsx +242 -0
  42. package/app/client/src/live/UploadDemo.tsx +21 -0
  43. package/app/client/src/main.tsx +4 -1
  44. package/app/client/src/pages/ApiTestPage.tsx +108 -0
  45. package/app/client/src/pages/HomePage.tsx +76 -0
  46. package/app/server/app.ts +1 -4
  47. package/app/server/controllers/users.controller.ts +36 -44
  48. package/app/server/index.ts +25 -35
  49. package/app/server/live/LiveChat.ts +77 -0
  50. package/app/server/live/LiveCounter.ts +67 -0
  51. package/app/server/live/LiveForm.ts +63 -0
  52. package/app/server/live/LiveLocalCounter.ts +32 -0
  53. package/app/server/live/LiveRoomChat.ts +285 -0
  54. package/app/server/live/LiveUpload.ts +81 -0
  55. package/app/server/routes/index.ts +3 -1
  56. package/app/server/routes/room.routes.ts +117 -0
  57. package/app/server/routes/users.routes.ts +35 -27
  58. package/app/shared/types/index.ts +14 -2
  59. package/config/app.config.ts +2 -62
  60. package/config/client.config.ts +2 -95
  61. package/config/database.config.ts +2 -99
  62. package/config/fluxstack.config.ts +25 -45
  63. package/config/index.ts +57 -38
  64. package/config/monitoring.config.ts +2 -114
  65. package/config/plugins.config.ts +2 -80
  66. package/config/server.config.ts +2 -68
  67. package/config/services.config.ts +2 -130
  68. package/config/system/app.config.ts +29 -0
  69. package/config/system/build.config.ts +49 -0
  70. package/config/system/client.config.ts +68 -0
  71. package/config/system/database.config.ts +17 -0
  72. package/config/system/fluxstack.config.ts +114 -0
  73. package/config/{logger.config.ts → system/logger.config.ts} +3 -1
  74. package/config/system/monitoring.config.ts +114 -0
  75. package/config/system/plugins.config.ts +84 -0
  76. package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
  77. package/config/system/server.config.ts +68 -0
  78. package/config/system/services.config.ts +46 -0
  79. package/config/{system.config.ts → system/system.config.ts} +1 -1
  80. package/core/build/flux-plugins-generator.ts +325 -325
  81. package/core/build/index.ts +39 -27
  82. package/core/build/live-components-generator.ts +3 -3
  83. package/core/build/optimizer.ts +235 -235
  84. package/core/cli/command-registry.ts +6 -4
  85. package/core/cli/commands/build.ts +79 -0
  86. package/core/cli/commands/create.ts +54 -0
  87. package/core/cli/commands/dev.ts +101 -0
  88. package/core/cli/commands/help.ts +34 -0
  89. package/core/cli/commands/index.ts +34 -0
  90. package/core/cli/commands/make-plugin.ts +90 -0
  91. package/core/cli/commands/plugin-add.ts +197 -0
  92. package/core/cli/commands/plugin-deps.ts +2 -2
  93. package/core/cli/commands/plugin-list.ts +208 -0
  94. package/core/cli/commands/plugin-remove.ts +170 -0
  95. package/core/cli/generators/component.ts +769 -769
  96. package/core/cli/generators/controller.ts +1 -1
  97. package/core/cli/generators/index.ts +146 -146
  98. package/core/cli/generators/interactive.ts +227 -227
  99. package/core/cli/generators/plugin.ts +2 -2
  100. package/core/cli/generators/prompts.ts +82 -82
  101. package/core/cli/generators/route.ts +6 -6
  102. package/core/cli/generators/service.ts +2 -2
  103. package/core/cli/generators/template-engine.ts +4 -3
  104. package/core/cli/generators/types.ts +2 -2
  105. package/core/cli/generators/utils.ts +191 -191
  106. package/core/cli/index.ts +115 -686
  107. package/core/cli/plugin-discovery.ts +2 -2
  108. package/core/client/LiveComponentsProvider.tsx +60 -8
  109. package/core/client/api/eden.ts +183 -0
  110. package/core/client/api/index.ts +11 -0
  111. package/core/client/components/Live.tsx +104 -0
  112. package/core/client/fluxstack.ts +1 -9
  113. package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
  114. package/core/client/hooks/state-validator.ts +1 -1
  115. package/core/client/hooks/useAuth.ts +48 -48
  116. package/core/client/hooks/useChunkedUpload.ts +85 -35
  117. package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
  118. package/core/client/hooks/useLiveComponent.ts +800 -0
  119. package/core/client/hooks/useLiveUpload.ts +71 -0
  120. package/core/client/hooks/useRoom.ts +409 -0
  121. package/core/client/hooks/useRoomProxy.ts +382 -0
  122. package/core/client/index.ts +17 -68
  123. package/core/client/standalone-entry.ts +8 -0
  124. package/core/client/standalone.ts +74 -53
  125. package/core/client/state/createStore.ts +192 -192
  126. package/core/client/state/index.ts +14 -14
  127. package/core/config/index.ts +70 -291
  128. package/core/config/schema.ts +42 -723
  129. package/core/framework/client.ts +131 -131
  130. package/core/framework/index.ts +7 -7
  131. package/core/framework/server.ts +47 -40
  132. package/core/framework/types.ts +2 -2
  133. package/core/index.ts +23 -4
  134. package/core/live/ComponentRegistry.ts +3 -3
  135. package/core/live/types.ts +77 -0
  136. package/core/plugins/built-in/index.ts +134 -134
  137. package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
  138. package/core/plugins/built-in/live-components/index.ts +1 -1
  139. package/core/plugins/built-in/monitoring/index.ts +111 -47
  140. package/core/plugins/built-in/static/index.ts +1 -1
  141. package/core/plugins/built-in/swagger/index.ts +68 -265
  142. package/core/plugins/built-in/vite/index.ts +85 -185
  143. package/core/plugins/built-in/vite/vite-dev.ts +10 -16
  144. package/core/plugins/config.ts +9 -7
  145. package/core/plugins/dependency-manager.ts +31 -1
  146. package/core/plugins/discovery.ts +19 -7
  147. package/core/plugins/executor.ts +2 -2
  148. package/core/plugins/index.ts +203 -203
  149. package/core/plugins/manager.ts +27 -39
  150. package/core/plugins/module-resolver.ts +19 -8
  151. package/core/plugins/registry.ts +255 -19
  152. package/core/plugins/types.ts +20 -53
  153. package/core/server/framework.ts +66 -43
  154. package/core/server/index.ts +15 -15
  155. package/core/server/live/ComponentRegistry.ts +78 -71
  156. package/core/server/live/FileUploadManager.ts +23 -10
  157. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  158. package/core/server/live/LiveRoomManager.ts +261 -0
  159. package/core/server/live/RoomEventBus.ts +234 -0
  160. package/core/server/live/RoomStateManager.ts +172 -0
  161. package/core/server/live/StateSignature.ts +643 -643
  162. package/core/server/live/WebSocketConnectionManager.ts +30 -19
  163. package/core/server/live/auto-generated-components.ts +21 -9
  164. package/core/server/live/index.ts +14 -0
  165. package/core/server/live/websocket-plugin.ts +214 -67
  166. package/core/server/middleware/elysia-helpers.ts +7 -2
  167. package/core/server/middleware/errorHandling.ts +1 -1
  168. package/core/server/middleware/index.ts +31 -31
  169. package/core/server/plugins/database.ts +180 -180
  170. package/core/server/plugins/static-files-plugin.ts +69 -69
  171. package/core/server/plugins/swagger.ts +1 -1
  172. package/core/server/rooms/RoomBroadcaster.ts +357 -0
  173. package/core/server/rooms/RoomSystem.ts +463 -0
  174. package/core/server/rooms/index.ts +13 -0
  175. package/core/server/services/BaseService.ts +1 -1
  176. package/core/server/services/ServiceContainer.ts +1 -1
  177. package/core/server/services/index.ts +8 -8
  178. package/core/templates/create-project.ts +12 -12
  179. package/core/testing/index.ts +9 -9
  180. package/core/testing/setup.ts +73 -73
  181. package/core/types/api.ts +168 -168
  182. package/core/types/build.ts +219 -219
  183. package/core/types/config.ts +56 -26
  184. package/core/types/index.ts +4 -4
  185. package/core/types/plugin.ts +107 -107
  186. package/core/types/types.ts +353 -14
  187. package/core/utils/build-logger.ts +324 -324
  188. package/core/utils/config-schema.ts +480 -480
  189. package/core/utils/env.ts +2 -8
  190. package/core/utils/errors/codes.ts +114 -114
  191. package/core/utils/errors/handlers.ts +36 -1
  192. package/core/utils/errors/index.ts +49 -5
  193. package/core/utils/errors/middleware.ts +113 -113
  194. package/core/utils/helpers.ts +6 -16
  195. package/core/utils/index.ts +17 -17
  196. package/core/utils/logger/colors.ts +114 -114
  197. package/core/utils/logger/config.ts +13 -9
  198. package/core/utils/logger/formatter.ts +82 -82
  199. package/core/utils/logger/group-logger.ts +101 -101
  200. package/core/utils/logger/index.ts +6 -1
  201. package/core/utils/logger/stack-trace.ts +3 -1
  202. package/core/utils/logger/startup-banner.ts +82 -82
  203. package/core/utils/logger/winston-logger.ts +152 -152
  204. package/core/utils/monitoring/index.ts +211 -211
  205. package/core/utils/sync-version.ts +66 -66
  206. package/core/utils/version.ts +1 -1
  207. package/create-fluxstack.ts +8 -7
  208. package/package.json +12 -13
  209. package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
  210. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  211. package/plugins/crypto-auth/client/components/index.ts +11 -11
  212. package/plugins/crypto-auth/client/index.ts +11 -11
  213. package/plugins/crypto-auth/config/index.ts +1 -1
  214. package/plugins/crypto-auth/index.ts +4 -4
  215. package/plugins/crypto-auth/package.json +65 -65
  216. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  217. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  218. package/plugins/crypto-auth/server/index.ts +21 -21
  219. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
  220. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
  221. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
  222. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
  223. package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
  224. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  225. package/tsconfig.api-strict.json +16 -0
  226. package/tsconfig.json +48 -52
  227. package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
  228. package/types/global.d.ts +29 -29
  229. package/types/vitest.d.ts +8 -8
  230. package/vite.config.ts +38 -62
  231. package/vitest.config.live.ts +10 -9
  232. package/vitest.config.ts +29 -17
  233. package/app/client/README.md +0 -69
  234. package/app/client/SIMPLIFICATION.md +0 -140
  235. package/app/client/frontend-only.ts +0 -12
  236. package/app/client/src/live/FileUploadExample.tsx +0 -359
  237. package/app/client/src/live/MinimalLiveClock.tsx +0 -47
  238. package/app/client/src/live/QuickUploadTest.tsx +0 -193
  239. package/app/client/tsconfig.app.json +0 -45
  240. package/app/client/tsconfig.json +0 -7
  241. package/app/client/zustand-setup.md +0 -65
  242. package/app/server/backend-only.ts +0 -18
  243. package/app/server/live/LiveClockComponent.ts +0 -215
  244. package/app/server/live/LiveFileUploadComponent.ts +0 -77
  245. package/app/server/routes/env-test.ts +0 -110
  246. package/core/client/hooks/index.ts +0 -7
  247. package/core/client/hooks/useHybridLiveComponent.ts +0 -685
  248. package/core/client/hooks/useTypedLiveComponent.ts +0 -133
  249. package/core/client/hooks/useWebSocket.ts +0 -361
  250. package/core/config/env.ts +0 -546
  251. package/core/config/loader.ts +0 -522
  252. package/core/config/runtime-config.ts +0 -327
  253. package/core/config/validator.ts +0 -540
  254. package/core/server/backend-entry.ts +0 -51
  255. package/core/server/standalone.ts +0 -106
  256. package/core/utils/regenerate-files.ts +0 -69
  257. package/fluxstack.config.ts +0 -354
@@ -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
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Backend Entry Point - Core Framework
3
- *
4
- * This file contains the protected logic for running backend standalone mode.
5
- * DO NOT modify this file directly - it's part of the FluxStack framework core.
6
- *
7
- * For customization, use app/server/backend-only.ts
8
- */
9
-
10
- import type { Elysia } from "elysia"
11
- import { startBackendOnly } from "./standalone"
12
-
13
- export interface BackendEntryConfig {
14
- port: number
15
- apiPrefix?: string
16
- host?: string
17
- }
18
-
19
- /**
20
- * Start backend in standalone mode
21
- *
22
- * @param apiRoutes - Elysia routes from app/server/routes
23
- * @param config - Backend configuration
24
- */
25
- export function startBackend(
26
- apiRoutes: Elysia,
27
- config: BackendEntryConfig
28
- ) {
29
- const { port, apiPrefix = '/api', host = 'localhost' } = config
30
-
31
- console.log(`🚀 Backend standalone: ${host}:${port}`)
32
- console.log(`📡 API Prefix: ${apiPrefix}`)
33
- console.log()
34
-
35
- // Start backend using the standalone utility
36
- startBackendOnly(apiRoutes, { port, apiPrefix })
37
- }
38
-
39
- /**
40
- * Create backend entry config from declarative config
41
- * Helper to make it easy to use with the config system
42
- */
43
- export function createBackendConfig(
44
- serverConfig: { server: { backendPort: number; apiPrefix: string; host: string } }
45
- ): BackendEntryConfig {
46
- return {
47
- port: serverConfig.server.backendPort,
48
- apiPrefix: serverConfig.server.apiPrefix,
49
- host: serverConfig.server.host
50
- }
51
- }
@@ -1,106 +0,0 @@
1
- // Standalone backend server (sem frontend integrado)
2
- import { FluxStackFramework } from "./index"
3
- import type { Plugin, PluginContext } from "../types"
4
-
5
- /**
6
- * Helper to safely parse request.url which might be relative or absolute
7
- */
8
- function parseRequestURL(request: Request): URL {
9
- try {
10
- // Try parsing as absolute URL first
11
- return new URL(request.url)
12
- } catch {
13
- // If relative, use host from headers or default to localhost
14
- const host = request.headers.get('host') || 'localhost'
15
- const protocol = request.headers.get('x-forwarded-proto') || 'http'
16
- return new URL(request.url, `${protocol}://${host}`)
17
- }
18
- }
19
-
20
- export const createStandaloneServer = (userConfig: any = {}) => {
21
- const app = new FluxStackFramework({
22
- server: {
23
- port: userConfig.port || parseInt(process.env.BACKEND_PORT || '3000'),
24
- host: 'localhost',
25
- apiPrefix: userConfig.apiPrefix || "/api",
26
- cors: {
27
- origins: ['*'],
28
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
29
- headers: ['Content-Type', 'Authorization'],
30
- credentials: false,
31
- maxAge: 86400
32
- },
33
- middleware: []
34
- },
35
- app: { name: 'FluxStack Backend', version: '1.7.4' },
36
- client: { port: 5173, proxy: { target: 'http://localhost:3000' }, build: { sourceMaps: true, minify: false, target: 'es2020', outDir: 'dist' } },
37
- ...userConfig
38
- })
39
-
40
- // Plugin de logging silencioso para standalone
41
- const silentLogger: Plugin = {
42
- name: "silent-logger",
43
- setup: (context: PluginContext) => {
44
- context.app.onRequest(({ request }: { request: Request }) => {
45
- // Log mais limpo para backend standalone
46
- const timestamp = new Date().toLocaleTimeString()
47
- const path = parseRequestURL(request).pathname
48
- console.log(`[${timestamp}] ${request.method} ${path}`)
49
- })
50
- }
51
- }
52
-
53
- app.use(silentLogger)
54
- return app
55
- }
56
-
57
- export const startBackendOnly = async (userRoutes?: any, config: any = {}) => {
58
- const port = config.port || process.env.BACKEND_PORT || 3000
59
- const host = process.env.HOST || 'localhost'
60
-
61
- console.log(`🦊 FluxStack Backend`)
62
- console.log(`🚀 http://${host}:${port}`)
63
- console.log(`📋 Health: http://${host}:${port}/health`)
64
- console.log()
65
-
66
- const app = createStandaloneServer(config)
67
-
68
- if (userRoutes) {
69
- app.routes(userRoutes)
70
- }
71
-
72
- // Adicionar rotas básicas para backend standalone
73
- const framework = app.getApp()
74
-
75
- // Health check
76
- framework.get("/health", () => ({
77
- status: "ok",
78
- mode: "backend-only",
79
- timestamp: new Date().toISOString(),
80
- port
81
- }))
82
-
83
- // Rota raiz informativa para backend standalone
84
- framework.get("/", () => ({
85
- message: "🦊 FluxStack Backend Server",
86
- mode: "backend-only",
87
- endpoints: {
88
- health: "/health",
89
- api: "/api/*",
90
- docs: "/swagger"
91
- },
92
- frontend: {
93
- note: "Frontend não está rodando neste servidor",
94
- recommendation: "Use 'bun run dev' para modo integrado ou 'bun run dev:frontend' para frontend standalone"
95
- },
96
- timestamp: new Date().toISOString()
97
- }))
98
-
99
- // Override do listen para não mostrar mensagens do framework
100
- const context = app.getContext()
101
- framework.listen(context.config.port!, () => {
102
- // Mensagem já foi mostrada acima, não repetir
103
- })
104
-
105
- return app
106
- }