create-fluxstack 1.0.13 → 1.0.15

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 (214) hide show
  1. package/.env.example +29 -29
  2. package/app/client/README.md +69 -69
  3. package/app/client/index.html +14 -13
  4. package/app/client/src/App.tsx +157 -524
  5. package/app/client/src/components/ErrorBoundary.tsx +107 -0
  6. package/app/client/src/components/ErrorDisplay.css +365 -0
  7. package/app/client/src/components/ErrorDisplay.tsx +258 -0
  8. package/app/client/src/components/FluxStackConfig.tsx +1321 -0
  9. package/app/client/src/components/HybridLiveCounter.tsx +140 -0
  10. package/app/client/src/components/LiveClock.tsx +286 -0
  11. package/app/client/src/components/MainLayout.tsx +390 -0
  12. package/app/client/src/components/SidebarNavigation.tsx +391 -0
  13. package/app/client/src/components/StateDemo.tsx +178 -0
  14. package/app/client/src/components/SystemMonitor.tsx +1038 -0
  15. package/app/client/src/components/Teste.tsx +104 -0
  16. package/app/client/src/components/UserProfile.tsx +809 -0
  17. package/app/client/src/hooks/useAuth.ts +39 -0
  18. package/app/client/src/hooks/useNotifications.ts +56 -0
  19. package/app/client/src/lib/eden-api.ts +189 -53
  20. package/app/client/src/lib/errors.ts +340 -0
  21. package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
  22. package/app/client/src/lib/index.ts +45 -0
  23. package/app/client/src/main.tsx +3 -2
  24. package/app/client/src/pages/ApiDocs.tsx +182 -0
  25. package/app/client/src/pages/Demo.tsx +174 -0
  26. package/app/client/src/pages/HybridLive.tsx +263 -0
  27. package/app/client/src/pages/Overview.tsx +155 -0
  28. package/app/client/src/store/README.md +43 -0
  29. package/app/client/src/store/index.ts +16 -0
  30. package/app/client/src/store/slices/uiSlice.ts +151 -0
  31. package/app/client/src/store/slices/userSlice.ts +161 -0
  32. package/app/client/src/test/README.md +257 -0
  33. package/app/client/src/test/setup.ts +70 -0
  34. package/app/client/src/test/types.ts +12 -0
  35. package/app/client/src/vite-env.d.ts +1 -1
  36. package/app/client/tsconfig.app.json +44 -43
  37. package/app/client/tsconfig.json +7 -7
  38. package/app/client/tsconfig.node.json +25 -25
  39. package/app/client/zustand-setup.md +65 -0
  40. package/app/server/controllers/users.controller.ts +68 -68
  41. package/app/server/index.ts +9 -1
  42. package/app/server/live/CounterComponent.ts +191 -0
  43. package/app/server/live/FluxStackConfig.ts +529 -0
  44. package/app/server/live/LiveClockComponent.ts +214 -0
  45. package/app/server/live/SidebarNavigation.ts +156 -0
  46. package/app/server/live/SystemMonitor.ts +594 -0
  47. package/app/server/live/SystemMonitorIntegration.ts +151 -0
  48. package/app/server/live/TesteComponent.ts +87 -0
  49. package/app/server/live/UserProfileComponent.ts +135 -0
  50. package/app/server/live/register-components.ts +28 -0
  51. package/app/server/middleware/auth.ts +136 -0
  52. package/app/server/middleware/errorHandling.ts +250 -0
  53. package/app/server/middleware/index.ts +10 -0
  54. package/app/server/middleware/rateLimit.ts +193 -0
  55. package/app/server/middleware/requestLogging.ts +215 -0
  56. package/app/server/middleware/validation.ts +270 -0
  57. package/app/server/routes/index.ts +14 -2
  58. package/app/server/routes/upload.ts +92 -0
  59. package/app/server/routes/users.routes.ts +2 -9
  60. package/app/server/services/NotificationService.ts +302 -0
  61. package/app/server/services/UserService.ts +222 -0
  62. package/app/server/services/index.ts +46 -0
  63. package/core/cli/commands/plugin-deps.ts +263 -0
  64. package/core/cli/generators/README.md +339 -0
  65. package/core/cli/generators/component.ts +770 -0
  66. package/core/cli/generators/controller.ts +299 -0
  67. package/core/cli/generators/index.ts +144 -0
  68. package/core/cli/generators/interactive.ts +228 -0
  69. package/core/cli/generators/prompts.ts +83 -0
  70. package/core/cli/generators/route.ts +513 -0
  71. package/core/cli/generators/service.ts +465 -0
  72. package/core/cli/generators/template-engine.ts +154 -0
  73. package/core/cli/generators/types.ts +71 -0
  74. package/core/cli/generators/utils.ts +192 -0
  75. package/core/cli/index.ts +69 -0
  76. package/core/cli/plugin-discovery.ts +16 -85
  77. package/core/client/fluxstack.ts +17 -0
  78. package/core/client/hooks/index.ts +7 -0
  79. package/core/client/hooks/state-validator.ts +130 -0
  80. package/core/client/hooks/useAuth.ts +49 -0
  81. package/core/client/hooks/useChunkedUpload.ts +258 -0
  82. package/core/client/hooks/useHybridLiveComponent.ts +967 -0
  83. package/core/client/hooks/useWebSocket.ts +373 -0
  84. package/core/client/index.ts +47 -0
  85. package/core/client/state/createStore.ts +193 -0
  86. package/core/client/state/index.ts +15 -0
  87. package/core/config/env-dynamic.ts +1 -1
  88. package/core/config/env.ts +2 -1
  89. package/core/config/runtime-config.ts +3 -3
  90. package/core/config/schema.ts +84 -49
  91. package/core/framework/server.ts +30 -0
  92. package/core/index.ts +25 -0
  93. package/core/live/ComponentRegistry.ts +399 -0
  94. package/core/live/types.ts +164 -0
  95. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
  96. package/core/plugins/built-in/live-components/index.ts +27 -0
  97. package/core/plugins/built-in/logger/index.ts +1 -1
  98. package/core/plugins/built-in/monitoring/index.ts +1 -1
  99. package/core/plugins/built-in/static/index.ts +1 -1
  100. package/core/plugins/built-in/swagger/index.ts +1 -1
  101. package/core/plugins/built-in/vite/index.ts +1 -1
  102. package/core/plugins/dependency-manager.ts +384 -0
  103. package/core/plugins/index.ts +5 -1
  104. package/core/plugins/manager.ts +7 -3
  105. package/core/plugins/registry.ts +88 -10
  106. package/core/plugins/types.ts +11 -11
  107. package/core/server/framework.ts +43 -0
  108. package/core/server/index.ts +11 -1
  109. package/core/server/live/ComponentRegistry.ts +1017 -0
  110. package/core/server/live/FileUploadManager.ts +272 -0
  111. package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
  112. package/core/server/live/SingleConnectionManager.ts +0 -0
  113. package/core/server/live/StateSignature.ts +644 -0
  114. package/core/server/live/WebSocketConnectionManager.ts +688 -0
  115. package/core/server/live/websocket-plugin.ts +435 -0
  116. package/core/server/middleware/errorHandling.ts +141 -0
  117. package/core/server/middleware/index.ts +16 -0
  118. package/core/server/plugins/static-files-plugin.ts +232 -0
  119. package/core/server/services/BaseService.ts +95 -0
  120. package/core/server/services/ServiceContainer.ts +144 -0
  121. package/core/server/services/index.ts +9 -0
  122. package/core/templates/create-project.ts +196 -33
  123. package/core/testing/index.ts +10 -0
  124. package/core/testing/setup.ts +74 -0
  125. package/core/types/build.ts +38 -14
  126. package/core/types/types.ts +319 -0
  127. package/core/utils/env-runtime.ts +7 -0
  128. package/core/utils/errors/handlers.ts +264 -39
  129. package/core/utils/errors/index.ts +528 -18
  130. package/core/utils/errors/middleware.ts +114 -0
  131. package/core/utils/logger/formatters.ts +222 -0
  132. package/core/utils/logger/index.ts +167 -48
  133. package/core/utils/logger/middleware.ts +253 -0
  134. package/core/utils/logger/performance.ts +384 -0
  135. package/core/utils/logger/transports.ts +365 -0
  136. package/create-fluxstack.ts +296 -296
  137. package/fluxstack.config.ts +17 -1
  138. package/package-template.json +66 -66
  139. package/package.json +31 -6
  140. package/public/README.md +16 -0
  141. package/vite.config.ts +29 -14
  142. package/.claude/settings.local.json +0 -74
  143. package/.github/workflows/ci-build-tests.yml +0 -480
  144. package/.github/workflows/dependency-management.yml +0 -324
  145. package/.github/workflows/release-validation.yml +0 -355
  146. package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
  147. package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
  148. package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
  149. package/CLAUDE.md +0 -200
  150. package/Dockerfile +0 -58
  151. package/Dockerfile.backend +0 -52
  152. package/Dockerfile.frontend +0 -54
  153. package/README-Docker.md +0 -85
  154. package/ai-context/00-QUICK-START.md +0 -86
  155. package/ai-context/README.md +0 -88
  156. package/ai-context/development/eden-treaty-guide.md +0 -362
  157. package/ai-context/development/patterns.md +0 -382
  158. package/ai-context/development/plugins-guide.md +0 -572
  159. package/ai-context/examples/crud-complete.md +0 -626
  160. package/ai-context/project/architecture.md +0 -399
  161. package/ai-context/project/overview.md +0 -213
  162. package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
  163. package/ai-context/recent-changes/type-inference-fix.md +0 -223
  164. package/ai-context/reference/environment-vars.md +0 -384
  165. package/ai-context/reference/troubleshooting.md +0 -407
  166. package/app/client/src/components/TestPage.tsx +0 -453
  167. package/bun.lock +0 -1063
  168. package/bunfig.toml +0 -16
  169. package/core/__tests__/integration.test.ts +0 -227
  170. package/core/build/index.ts +0 -186
  171. package/core/config/__tests__/config-loader.test.ts +0 -554
  172. package/core/config/__tests__/config-merger.test.ts +0 -657
  173. package/core/config/__tests__/env-converter.test.ts +0 -372
  174. package/core/config/__tests__/env-processor.test.ts +0 -431
  175. package/core/config/__tests__/env.test.ts +0 -452
  176. package/core/config/__tests__/integration.test.ts +0 -418
  177. package/core/config/__tests__/loader.test.ts +0 -331
  178. package/core/config/__tests__/schema.test.ts +0 -129
  179. package/core/config/__tests__/validator.test.ts +0 -318
  180. package/core/framework/__tests__/server.test.ts +0 -233
  181. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  182. package/core/plugins/__tests__/manager.test.ts +0 -398
  183. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  184. package/core/plugins/__tests__/registry.test.ts +0 -335
  185. package/core/utils/__tests__/errors.test.ts +0 -139
  186. package/core/utils/__tests__/helpers.test.ts +0 -297
  187. package/core/utils/__tests__/logger.test.ts +0 -141
  188. package/create-test-app.ts +0 -156
  189. package/docker-compose.microservices.yml +0 -75
  190. package/docker-compose.simple.yml +0 -57
  191. package/docker-compose.yml +0 -71
  192. package/eslint.config.js +0 -23
  193. package/flux-cli.ts +0 -214
  194. package/nginx-lb.conf +0 -37
  195. package/publish.sh +0 -63
  196. package/run-clean.ts +0 -26
  197. package/run-env-tests.ts +0 -313
  198. package/tailwind.config.js +0 -34
  199. package/tests/__mocks__/api.ts +0 -56
  200. package/tests/fixtures/users.ts +0 -69
  201. package/tests/integration/api/users.routes.test.ts +0 -221
  202. package/tests/setup.ts +0 -29
  203. package/tests/unit/app/client/App-simple.test.tsx +0 -56
  204. package/tests/unit/app/client/App.test.tsx.skip +0 -237
  205. package/tests/unit/app/client/eden-api.test.ts +0 -186
  206. package/tests/unit/app/client/simple.test.tsx +0 -23
  207. package/tests/unit/app/controllers/users.controller.test.ts +0 -150
  208. package/tests/unit/core/create-project.test.ts.skip +0 -95
  209. package/tests/unit/core/framework.test.ts +0 -144
  210. package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
  211. package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
  212. package/tests/utils/test-helpers.ts +0 -61
  213. package/vitest.config.ts +0 -50
  214. package/workspace.json +0 -6
package/run-env-tests.ts DELETED
@@ -1,313 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /**
4
- * Test Runner for Environment Variable Loading System
5
- * Comprehensive test suite for FluxStack environment configuration
6
- */
7
-
8
- import { expect } from 'bun:test'
9
- import {
10
- EnvironmentProcessor,
11
- EnvConverter,
12
- getEnvironmentInfo,
13
- ConfigMerger,
14
- EnvironmentConfigApplier
15
- } from './core/config/env'
16
- import { getConfigSync } from './core/config'
17
-
18
- // ANSI color codes for output
19
- const colors = {
20
- green: '\x1b[32m',
21
- red: '\x1b[31m',
22
- yellow: '\x1b[33m',
23
- blue: '\x1b[34m',
24
- reset: '\x1b[0m',
25
- bold: '\x1b[1m'
26
- }
27
-
28
- let testsPassed = 0
29
- let testsFailed = 0
30
- let testsTotal = 0
31
-
32
- function test(name: string, fn: () => void | Promise<void>) {
33
- testsTotal++
34
- try {
35
- const result = fn()
36
- if (result instanceof Promise) {
37
- result.then(() => {
38
- testsPassed++
39
- console.log(`${colors.green}✓${colors.reset} ${name}`)
40
- }).catch((error) => {
41
- testsFailed++
42
- console.log(`${colors.red}✗${colors.reset} ${name}`)
43
- console.log(` ${colors.red}Error: ${error.message}${colors.reset}`)
44
- })
45
- } else {
46
- testsPassed++
47
- console.log(`${colors.green}✓${colors.reset} ${name}`)
48
- }
49
- } catch (error) {
50
- testsFailed++
51
- console.log(`${colors.red}✗${colors.reset} ${name}`)
52
- console.log(` ${colors.red}Error: ${(error as Error).message}${colors.reset}`)
53
- }
54
- }
55
-
56
- function describe(name: string, fn: () => void) {
57
- console.log(`\n${colors.bold}${colors.blue}${name}${colors.reset}`)
58
- fn()
59
- }
60
-
61
- // Save original environment
62
- const originalEnv = { ...process.env }
63
-
64
- function beforeEach() {
65
- // Clear test environment variables
66
- for (const key in process.env) {
67
- if (key.startsWith('FLUXSTACK_') || key.startsWith('PORT') || key.startsWith('HOST') ||
68
- key.startsWith('CORS_') || key.startsWith('LOG_') || key.startsWith('BUILD_') ||
69
- key.startsWith('DATABASE_') || key.startsWith('JWT_') || key.startsWith('SMTP_') ||
70
- key.startsWith('VITE_') || key.startsWith('API_') || key.startsWith('CLIENT_') ||
71
- key.startsWith('MONITORING_') || key.startsWith('METRICS_') || key.startsWith('PROFILING_')) {
72
- delete process.env[key]
73
- }
74
- }
75
- }
76
-
77
- function afterEach() {
78
- // Restore original environment
79
- process.env = { ...originalEnv }
80
- }
81
-
82
- // Test Suite
83
- console.log(`${colors.bold}FluxStack Environment Variable Loading Tests${colors.reset}\n`)
84
-
85
- describe('EnvConverter Type Conversion', () => {
86
- test('converts numbers correctly', () => {
87
- expect(EnvConverter.toNumber('123', 0)).toBe(123)
88
- expect(EnvConverter.toNumber('invalid', 42)).toBe(42)
89
- expect(EnvConverter.toNumber(undefined, 42)).toBe(42)
90
- })
91
-
92
- test('converts booleans correctly', () => {
93
- expect(EnvConverter.toBoolean('true', false)).toBe(true)
94
- expect(EnvConverter.toBoolean('1', false)).toBe(true)
95
- expect(EnvConverter.toBoolean('false', true)).toBe(false)
96
- expect(EnvConverter.toBoolean('invalid', true)).toBe(false)
97
- })
98
-
99
- test('converts arrays correctly', () => {
100
- expect(EnvConverter.toArray('a,b,c')).toEqual(['a', 'b', 'c'])
101
- expect(EnvConverter.toArray('a, b , c')).toEqual(['a', 'b', 'c'])
102
- expect(EnvConverter.toArray('')).toEqual([])
103
- })
104
-
105
- test('converts log levels correctly', () => {
106
- expect(EnvConverter.toLogLevel('debug', 'info')).toBe('debug')
107
- expect(EnvConverter.toLogLevel('invalid', 'info')).toBe('info')
108
- })
109
- })
110
-
111
- describe('EnvironmentProcessor', () => {
112
- let processor: EnvironmentProcessor
113
-
114
- beforeEach()
115
- processor = new EnvironmentProcessor()
116
-
117
- test('processes server configuration', () => {
118
- process.env.PORT = '8080'
119
- process.env.HOST = 'example.com'
120
- process.env.FLUXSTACK_API_PREFIX = '/v1'
121
-
122
- const config = processor.processEnvironmentVariables()
123
-
124
- expect(config.server?.port).toBe(8080)
125
- expect(config.server?.host).toBe('example.com')
126
- expect(config.server?.apiPrefix).toBe('/v1')
127
- })
128
-
129
- test('processes CORS configuration', () => {
130
- process.env.CORS_ORIGINS = 'http://localhost:3000,https://example.com'
131
- process.env.CORS_METHODS = 'GET,POST,PUT'
132
- process.env.CORS_CREDENTIALS = 'true'
133
-
134
- const config = processor.processEnvironmentVariables()
135
-
136
- expect(config.server?.cors?.origins).toEqual(['http://localhost:3000', 'https://example.com'])
137
- expect(config.server?.cors?.methods).toEqual(['GET', 'POST', 'PUT'])
138
- expect(config.server?.cors?.credentials).toBe(true)
139
- })
140
-
141
- test('processes database configuration', () => {
142
- process.env.DATABASE_URL = 'postgresql://user:pass@localhost:5432/db'
143
- process.env.DATABASE_SSL = 'true'
144
- process.env.DATABASE_POOL_SIZE = '20'
145
-
146
- const config = processor.processEnvironmentVariables()
147
-
148
- expect(config.database?.url).toBe('postgresql://user:pass@localhost:5432/db')
149
- expect(config.database?.ssl).toBe(true)
150
- expect(config.database?.poolSize).toBe(20)
151
- })
152
-
153
- afterEach()
154
- })
155
-
156
- describe('Configuration Loading Integration', () => {
157
- test('loads complete development configuration', () => {
158
- beforeEach()
159
-
160
- process.env.NODE_ENV = 'development'
161
- process.env.PORT = '3000'
162
- process.env.HOST = 'localhost'
163
- process.env.LOG_LEVEL = 'debug'
164
- process.env.CORS_ORIGINS = 'http://localhost:3000,http://localhost:5173'
165
-
166
- const config = getConfigSync()
167
-
168
- expect(getEnvironmentInfo().isDevelopment).toBe(true)
169
- expect(config.server?.port).toBe(3000)
170
- expect(config.server?.host).toBe('localhost')
171
- expect(config.logging?.level).toBe('debug')
172
- expect(config.server?.cors?.origins).toEqual(['http://localhost:3000', 'http://localhost:5173'])
173
-
174
- afterEach()
175
- })
176
-
177
- test('loads complete production configuration', () => {
178
- beforeEach()
179
-
180
- process.env.NODE_ENV = 'production'
181
- process.env.PORT = '8080'
182
- process.env.HOST = '0.0.0.0'
183
- process.env.LOG_LEVEL = 'warn'
184
- process.env.LOG_FORMAT = 'json'
185
- process.env.MONITORING_ENABLED = 'true'
186
- process.env.BUILD_MINIFY = 'true'
187
-
188
- const config = getConfigSync()
189
-
190
- expect(getEnvironmentInfo().isProduction).toBe(true)
191
- expect(config.server?.port).toBe(8080)
192
- expect(config.server?.host).toBe('0.0.0.0')
193
- expect(config.logging?.level).toBe('warn')
194
- expect(config.logging?.format).toBe('json')
195
- expect(config.monitoring?.enabled).toBe(true)
196
- expect(config.build?.optimization?.minify).toBe(true)
197
-
198
- afterEach()
199
- })
200
-
201
- test('handles precedence correctly', () => {
202
- beforeEach()
203
-
204
- // Test precedence: FLUXSTACK_ prefix vs standard
205
- process.env.PORT = '3000'
206
- process.env.FLUXSTACK_PORT = '4000'
207
- process.env.API_PREFIX = '/api'
208
- process.env.FLUXSTACK_API_PREFIX = '/v2'
209
-
210
- const config = getConfigSync()
211
-
212
- // Current implementation uses || operator, so first non-empty wins
213
- expect(config.server?.port).toBe(3000) // PORT wins because it's checked first
214
- expect(config.server?.apiPrefix).toBe('/v2') // FLUXSTACK_API_PREFIX wins
215
-
216
- afterEach()
217
- })
218
- })
219
-
220
- describe('ConfigMerger', () => {
221
- test('merges configurations with precedence', () => {
222
- const merger = new ConfigMerger()
223
-
224
- const config1 = {
225
- config: { server: { port: 3000, host: 'localhost' } },
226
- source: 'default'
227
- }
228
-
229
- const config2 = {
230
- config: { server: { port: 4000 } },
231
- source: 'environment'
232
- }
233
-
234
- const result = merger.merge(config1, config2)
235
-
236
- expect(result.server?.port).toBe(4000) // Environment overrides default
237
- expect(result.server?.host).toBe('localhost') // Preserved from default
238
- })
239
- })
240
-
241
- describe('Real-world Scenarios', () => {
242
- test('Docker deployment scenario', () => {
243
- beforeEach()
244
-
245
- process.env.NODE_ENV = 'production'
246
- process.env.PORT = '8080'
247
- process.env.HOST = '0.0.0.0'
248
- process.env.DATABASE_URL = 'postgresql://user:pass@postgres:5432/app'
249
- process.env.LOG_FORMAT = 'json'
250
- process.env.MONITORING_ENABLED = 'true'
251
-
252
- const config = getConfigSync()
253
-
254
- expect(config.server?.port).toBe(8080)
255
- expect(config.server?.host).toBe('0.0.0.0')
256
- expect(config.database?.url).toBe('postgresql://user:pass@postgres:5432/app')
257
- expect(config.logging?.format).toBe('json')
258
- expect(config.monitoring?.enabled).toBe(true)
259
-
260
- afterEach()
261
- })
262
-
263
- test('handles complex nested configuration', () => {
264
- beforeEach()
265
-
266
- process.env.CORS_ORIGINS = 'http://localhost:3000,https://myapp.com'
267
- process.env.CORS_METHODS = 'GET,POST,PUT,DELETE'
268
- process.env.CORS_CREDENTIALS = 'true'
269
- process.env.CORS_MAX_AGE = '86400'
270
-
271
- const config = getConfigSync()
272
-
273
- expect(config.server?.cors?.origins).toEqual(['http://localhost:3000', 'https://myapp.com'])
274
- expect(config.server?.cors?.methods).toEqual(['GET', 'POST', 'PUT', 'DELETE'])
275
- expect(config.server?.cors?.credentials).toBe(true)
276
- expect(config.server?.cors?.maxAge).toBe(86400)
277
-
278
- afterEach()
279
- })
280
-
281
- test('handles invalid environment variables gracefully', () => {
282
- beforeEach()
283
-
284
- process.env.PORT = 'invalid'
285
- process.env.LOG_LEVEL = 'invalid'
286
- process.env.MONITORING_ENABLED = 'maybe'
287
-
288
- const config = getConfigSync()
289
-
290
- expect(typeof config.server?.port).toBe('number')
291
- // Log level should be valid (invalid falls back to default)
292
- expect(typeof config.logging?.level).toBe('string')
293
- expect(typeof config.monitoring?.enabled).toBe('boolean')
294
-
295
- afterEach()
296
- })
297
- })
298
-
299
- // Run summary
300
- setTimeout(() => {
301
- console.log(`\n${colors.bold}Test Results:${colors.reset}`)
302
- console.log(`${colors.green}✓ Passed: ${testsPassed}${colors.reset}`)
303
- console.log(`${colors.red}✗ Failed: ${testsFailed}${colors.reset}`)
304
- console.log(`${colors.blue}Total: ${testsTotal}${colors.reset}`)
305
-
306
- if (testsFailed === 0) {
307
- console.log(`\n${colors.green}${colors.bold}🎉 All tests passed!${colors.reset}`)
308
- process.exit(0)
309
- } else {
310
- console.log(`\n${colors.red}${colors.bold}❌ Some tests failed${colors.reset}`)
311
- process.exit(1)
312
- }
313
- }, 100) // Give async tests time to complete
@@ -1,34 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- export default {
3
- content: [
4
- "./app/client/index.html",
5
- "./app/client/src/**/*.{js,ts,jsx,tsx}",
6
- ],
7
- theme: {
8
- extend: {
9
- colors: {
10
- // Custom colors for FluxStack branding
11
- flux: {
12
- 50: '#f0f9ff',
13
- 100: '#e0f2fe',
14
- 200: '#bae6fd',
15
- 300: '#7dd3fc',
16
- 400: '#38bdf8',
17
- 500: '#0ea5e9',
18
- 600: '#0284c7',
19
- 700: '#0369a1',
20
- 800: '#075985',
21
- 900: '#0c4a6e',
22
- }
23
- },
24
- fontFamily: {
25
- sans: ['-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'sans-serif'],
26
- },
27
- animation: {
28
- 'spin-slow': 'spin 3s linear infinite',
29
- 'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
30
- }
31
- },
32
- },
33
- plugins: [],
34
- }
@@ -1,56 +0,0 @@
1
- // Mock API responses for testing
2
- export const mockApiResponses = {
3
- users: {
4
- list: {
5
- users: [
6
- {
7
- id: 1,
8
- name: 'Mock User 1',
9
- email: 'mock1@example.com',
10
- createdAt: new Date('2024-01-01')
11
- },
12
- {
13
- id: 2,
14
- name: 'Mock User 2',
15
- email: 'mock2@example.com',
16
- createdAt: new Date('2024-01-02')
17
- }
18
- ]
19
- },
20
- create: {
21
- success: true,
22
- user: {
23
- id: 3,
24
- name: 'New Mock User',
25
- email: 'newmock@example.com',
26
- createdAt: new Date()
27
- }
28
- },
29
- error: {
30
- success: false,
31
- message: 'Mock error message'
32
- }
33
- },
34
- api: {
35
- index: {
36
- message: 'Hello from Mock FluxStack API!'
37
- }
38
- }
39
- }
40
-
41
- export const mockApi = {
42
- api: {
43
- index: {
44
- get: () => Promise.resolve({ data: mockApiResponses.api.index })
45
- },
46
- users: {
47
- get: () => Promise.resolve({ data: mockApiResponses.users.list }),
48
- post: (body: any) => {
49
- if (body.email === 'error@test.com') {
50
- return Promise.resolve({ data: mockApiResponses.users.error })
51
- }
52
- return Promise.resolve({ data: mockApiResponses.users.create })
53
- }
54
- }
55
- }
56
- }
@@ -1,69 +0,0 @@
1
- import type { User, CreateUserRequest } from '@/app/shared/types'
2
-
3
- export const mockUsers: User[] = [
4
- {
5
- id: 1,
6
- name: 'João Silva',
7
- email: 'joao@example.com',
8
- createdAt: new Date('2024-01-01T10:00:00Z')
9
- },
10
- {
11
- id: 2,
12
- name: 'Maria Santos',
13
- email: 'maria@example.com',
14
- createdAt: new Date('2024-01-02T11:00:00Z')
15
- },
16
- {
17
- id: 3,
18
- name: 'Pedro Costa',
19
- email: 'pedro@example.com',
20
- createdAt: new Date('2024-01-03T12:00:00Z')
21
- }
22
- ]
23
-
24
- export const validUserRequests: CreateUserRequest[] = [
25
- {
26
- name: 'Ana Lima',
27
- email: 'ana@example.com'
28
- },
29
- {
30
- name: 'Carlos Oliveira',
31
- email: 'carlos@example.com'
32
- },
33
- {
34
- name: 'Teste User',
35
- email: 'teste@example.com'
36
- }
37
- ]
38
-
39
- export const invalidUserRequests = [
40
- {
41
- name: 'A', // Too short
42
- email: 'valid@example.com'
43
- },
44
- {
45
- name: 'Valid Name',
46
- email: 'invalid-email' // Invalid format
47
- },
48
- {
49
- name: '', // Empty name
50
- email: 'empty@example.com'
51
- },
52
- {
53
- name: 'Valid Name',
54
- email: '' // Empty email
55
- },
56
- {
57
- name: 'Valid Name'
58
- // Missing email
59
- },
60
- {
61
- email: 'missing@example.com'
62
- // Missing name
63
- }
64
- ]
65
-
66
- export const duplicateEmailRequest: CreateUserRequest = {
67
- name: 'Duplicate User',
68
- email: 'joao@example.com' // Same as first mock user
69
- }
@@ -1,221 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest'
2
- import { Elysia } from 'elysia'
3
- import { usersRoutes } from '@/app/server/routes/users.routes'
4
-
5
- describe('Users API Routes', () => {
6
- let app: Elysia
7
-
8
- beforeEach(() => {
9
- // Create a fresh Elysia app for each test
10
- app = new Elysia().use(usersRoutes)
11
- })
12
-
13
- describe('GET /users', () => {
14
- it('should return users list', async () => {
15
- const response = await app
16
- .handle(new Request('http://localhost/users'))
17
-
18
- expect(response.status).toBe(200)
19
-
20
- const data = await response.json()
21
- expect(data).toBeDefined()
22
- expect(data.users).toBeDefined()
23
- expect(Array.isArray(data.users)).toBe(true)
24
- })
25
-
26
- it('should return users with correct structure', async () => {
27
- const response = await app
28
- .handle(new Request('http://localhost/users'))
29
-
30
- const data = await response.json()
31
-
32
- if (data.users.length > 0) {
33
- const user = data.users[0]
34
- expect(user).toHaveProperty('id')
35
- expect(user).toHaveProperty('name')
36
- expect(user).toHaveProperty('email')
37
- expect(user).toHaveProperty('createdAt')
38
- }
39
- })
40
- })
41
-
42
- describe('GET /users/:id', () => {
43
- it('should return user by ID', async () => {
44
- // First get all users to find a valid ID
45
- const usersResponse = await app
46
- .handle(new Request('http://localhost/users'))
47
- const usersData = await usersResponse.json()
48
-
49
- if (usersData.users.length > 0) {
50
- const userId = usersData.users[0].id
51
-
52
- const response = await app
53
- .handle(new Request(`http://localhost/users/${userId}`))
54
-
55
- expect(response.status).toBe(200)
56
-
57
- const data = await response.json()
58
- expect(data.user).toBeDefined()
59
- expect(data.user.id).toBe(userId)
60
- }
61
- })
62
-
63
- it('should return error for non-existent user', async () => {
64
- const response = await app
65
- .handle(new Request('http://localhost/users/99999'))
66
-
67
- expect(response.status).toBe(200) // Elysia returns 200 by default
68
-
69
- // Check if response has content before parsing JSON
70
- const text = await response.text()
71
- if (text) {
72
- const data = JSON.parse(text)
73
- expect(data.error).toBe('Usuário não encontrado')
74
- } else {
75
- // If no response body, the test still passes as the behavior is expected
76
- expect(response.status).toBe(200)
77
- }
78
- })
79
-
80
- it('should validate ID parameter', async () => {
81
- const response = await app
82
- .handle(new Request('http://localhost/users/invalid-id'))
83
-
84
- // Should handle invalid ID gracefully
85
- expect(response.status).toBeGreaterThanOrEqual(200)
86
- })
87
- })
88
-
89
- describe('POST /users', () => {
90
- it('should create new user with valid data', async () => {
91
- const userData = {
92
- name: 'Integration Test User',
93
- email: 'integration@test.com'
94
- }
95
-
96
- const response = await app
97
- .handle(new Request('http://localhost/users', {
98
- method: 'POST',
99
- headers: { 'Content-Type': 'application/json' },
100
- body: JSON.stringify(userData)
101
- }))
102
-
103
- expect(response.status).toBe(200)
104
-
105
- const data = await response.json()
106
- expect(data.success).toBe(true)
107
- expect(data.user).toBeDefined()
108
- expect(data.user.name).toBe(userData.name)
109
- expect(data.user.email).toBe(userData.email)
110
- expect(data.user.id).toBeDefined()
111
- })
112
-
113
- it('should reject user with invalid data', async () => {
114
- const invalidData = {
115
- name: 'A', // Too short
116
- email: 'invalid-email' // Invalid format
117
- }
118
-
119
- const response = await app
120
- .handle(new Request('http://localhost/users', {
121
- method: 'POST',
122
- headers: { 'Content-Type': 'application/json' },
123
- body: JSON.stringify(invalidData)
124
- }))
125
-
126
- expect(response.status).toBe(400)
127
-
128
- const data = await response.json()
129
- expect(data.success).toBe(false)
130
- expect(data.error).toBeDefined()
131
- })
132
-
133
- it('should reject user with missing fields', async () => {
134
- const incompleteData = {
135
- name: 'Test User'
136
- // Missing email
137
- }
138
-
139
- const response = await app
140
- .handle(new Request('http://localhost/users', {
141
- method: 'POST',
142
- headers: { 'Content-Type': 'application/json' },
143
- body: JSON.stringify(incompleteData)
144
- }))
145
-
146
- expect(response.status).toBe(400)
147
- })
148
-
149
- it('should prevent duplicate emails', async () => {
150
- const userData = {
151
- name: 'Duplicate Test User',
152
- email: 'duplicate@integration.test'
153
- }
154
-
155
- // Create first user
156
- const firstResponse = await app
157
- .handle(new Request('http://localhost/users', {
158
- method: 'POST',
159
- headers: { 'Content-Type': 'application/json' },
160
- body: JSON.stringify(userData)
161
- }))
162
-
163
- expect(firstResponse.status).toBe(200)
164
-
165
- // Try to create user with same email
166
- const secondResponse = await app
167
- .handle(new Request('http://localhost/users', {
168
- method: 'POST',
169
- headers: { 'Content-Type': 'application/json' },
170
- body: JSON.stringify(userData)
171
- }))
172
-
173
- const data = await secondResponse.json()
174
- expect(data.success).toBe(false)
175
- expect(data.message).toBe('Email já está em uso')
176
- })
177
- })
178
-
179
- describe('DELETE /users/:id', () => {
180
- it('should delete existing user', async () => {
181
- // First create a user to delete
182
- const userData = {
183
- name: 'User to Delete',
184
- email: 'delete@test.com'
185
- }
186
-
187
- const createResponse = await app
188
- .handle(new Request('http://localhost/users', {
189
- method: 'POST',
190
- headers: { 'Content-Type': 'application/json' },
191
- body: JSON.stringify(userData)
192
- }))
193
-
194
- const createData = await createResponse.json()
195
- const userId = createData.user.id
196
-
197
- // Now delete the user
198
- const deleteResponse = await app
199
- .handle(new Request(`http://localhost/users/${userId}`, {
200
- method: 'DELETE'
201
- }))
202
-
203
- expect(deleteResponse.status).toBe(200)
204
-
205
- const deleteData = await deleteResponse.json()
206
- expect(deleteData.success).toBe(true)
207
- expect(deleteData.message).toBe('Usuário deletado com sucesso')
208
- })
209
-
210
- it('should return error when deleting non-existent user', async () => {
211
- const response = await app
212
- .handle(new Request('http://localhost/users/99999', {
213
- method: 'DELETE'
214
- }))
215
-
216
- const data = await response.json()
217
- expect(data.success).toBe(false)
218
- expect(data.message).toBe('Usuário não encontrado')
219
- })
220
- })
221
- })