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
@@ -1,95 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2
- import { ProjectCreator } from '@/core/templates/create-project'
3
- import { rmdir, mkdir } from 'fs/promises'
4
- import { join } from 'path'
5
-
6
- // Mock bun APIs to avoid actual file operations in tests
7
- vi.mock('bun', async () => {
8
- const actual = await vi.importActual('bun')
9
- return {
10
- ...actual,
11
- spawn: vi.fn(() => ({
12
- exited: Promise.resolve(0),
13
- stdout: { readable: null },
14
- stderr: { readable: null }
15
- })),
16
- write: vi.fn(),
17
- file: vi.fn(() => ({
18
- exists: () => true,
19
- text: () => 'mock content'
20
- }))
21
- }
22
- })
23
-
24
- vi.mock('fs/promises', () => ({
25
- mkdir: vi.fn(),
26
- readdir: vi.fn(() => [])
27
- }))
28
-
29
- describe('ProjectCreator', () => {
30
- const testDir = join(process.cwd(), 'test-project-temp')
31
- let creator: ProjectCreator
32
-
33
- beforeEach(() => {
34
- creator = new ProjectCreator({
35
- name: 'test-project',
36
- targetDir: testDir,
37
- template: 'basic'
38
- })
39
- vi.clearAllMocks()
40
- })
41
-
42
- afterEach(async () => {
43
- try {
44
- await rmdir(testDir, { recursive: true })
45
- } catch {
46
- // Ignore cleanup errors
47
- }
48
- })
49
-
50
- describe('constructor', () => {
51
- it('should create ProjectCreator with basic options', () => {
52
- expect(creator).toBeDefined()
53
- })
54
-
55
- it('should set default template to basic', () => {
56
- const defaultCreator = new ProjectCreator({
57
- name: 'test-project'
58
- })
59
- expect(defaultCreator).toBeDefined()
60
- })
61
-
62
- it('should handle custom target directory', () => {
63
- const customCreator = new ProjectCreator({
64
- name: 'custom-project',
65
- targetDir: '/custom/path',
66
- template: 'full'
67
- })
68
- expect(customCreator).toBeDefined()
69
- })
70
- })
71
-
72
- describe('validation', () => {
73
- it('should validate project names correctly', () => {
74
- // Valid names
75
- expect(() => new ProjectCreator({ name: 'valid-name' })).not.toThrow()
76
- expect(() => new ProjectCreator({ name: 'valid_name' })).not.toThrow()
77
- expect(() => new ProjectCreator({ name: 'validName123' })).not.toThrow()
78
- })
79
- })
80
-
81
- describe('create method', () => {
82
- it('should handle create process without throwing', async () => {
83
- // Mock all async operations to succeed
84
- const mkdirMock = vi.mocked(mkdir)
85
- mkdirMock.mockResolvedValue(undefined)
86
-
87
- // We'll test that the method doesn't throw
88
- // Full integration testing would require actual file system operations
89
- expect(async () => {
90
- // In a real test, we'd mock all the dependencies properly
91
- // For now, we just ensure the class is properly structured
92
- }).not.toThrow()
93
- })
94
- })
95
- })
@@ -1,144 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest'
2
- import { FluxStackFramework } from '@/core/server/framework'
3
- import type { Plugin } from '@/core/types'
4
- import type { FluxStackConfig } from '@/core/config/schema'
5
-
6
- describe('FluxStackFramework', () => {
7
- let framework: FluxStackFramework
8
-
9
- beforeEach(() => {
10
- framework = new FluxStackFramework({
11
- server: {
12
- port: 3001,
13
- host: 'localhost',
14
- apiPrefix: '/api',
15
- cors: {
16
- origins: ['*'],
17
- methods: ['GET', 'POST'],
18
- headers: ['Content-Type'],
19
- credentials: false,
20
- maxAge: 86400
21
- },
22
- middleware: []
23
- }
24
- })
25
- })
26
-
27
- describe('constructor', () => {
28
- it('should create framework with default config', () => {
29
- const defaultFramework = new FluxStackFramework()
30
- const context = defaultFramework.getContext()
31
-
32
- // Environment variables now control default values
33
- expect(context.config.server.port).toBeDefined()
34
- expect(context.config.server.apiPrefix).toBe('/api')
35
- expect(context.config.client.port).toBeDefined()
36
- })
37
-
38
- it('should create framework with custom config', () => {
39
- const config: Partial<FluxStackConfig> = {
40
- server: {
41
- port: 4000,
42
- host: 'localhost',
43
- apiPrefix: '/custom-api',
44
- cors: {
45
- origins: ['*'],
46
- methods: ['GET', 'POST'],
47
- headers: ['Content-Type'],
48
- credentials: false,
49
- maxAge: 86400
50
- },
51
- middleware: []
52
- },
53
- client: {
54
- port: 5174,
55
- proxy: {
56
- target: 'http://localhost:4000',
57
- changeOrigin: true
58
- },
59
- build: {
60
- outDir: 'dist/client',
61
- sourceMaps: true,
62
- minify: false,
63
- target: 'es2020'
64
- }
65
- }
66
- }
67
-
68
- const customFramework = new FluxStackFramework(config)
69
- const context = customFramework.getContext()
70
-
71
- expect(context.config.server.port).toBe(4000)
72
- expect(context.config.client.port).toBe(5174)
73
- expect(context.config.server.apiPrefix).toBe('/custom-api')
74
- })
75
-
76
- it('should set development mode correctly', () => {
77
- const context = framework.getContext()
78
- // Environment config manages NODE_ENV now
79
- expect(typeof context.isDevelopment).toBe('boolean')
80
- expect(typeof context.isProduction).toBe('boolean')
81
- })
82
- })
83
-
84
- describe('plugin system', () => {
85
- it('should add plugins correctly', () => {
86
- const mockPlugin: Plugin = {
87
- name: 'test-plugin',
88
- setup: () => {}
89
- }
90
-
91
- const result = framework.use(mockPlugin)
92
- expect(result).toBe(framework) // Should return framework for chaining
93
- })
94
-
95
- it('should handle multiple plugins', () => {
96
- const plugin1: Plugin = {
97
- name: 'plugin-1',
98
- setup: () => {}
99
- }
100
-
101
- const plugin2: Plugin = {
102
- name: 'plugin-2',
103
- setup: () => {}
104
- }
105
-
106
- framework.use(plugin1).use(plugin2)
107
- // Framework should not throw and should allow chaining
108
- expect(framework).toBeDefined()
109
- })
110
- })
111
-
112
- describe('routes', () => {
113
- it('should register routes correctly', () => {
114
- // Test that routes method exists and returns framework
115
- expect(typeof framework.routes).toBe('function')
116
-
117
- // Skip actual route registration test to avoid Elysia mock complexity
118
- // This test verifies the method is available for chaining
119
- expect(framework).toBeDefined()
120
- })
121
- })
122
-
123
- describe('getApp', () => {
124
- it('should return Elysia app instance', () => {
125
- const app = framework.getApp()
126
- expect(app).toBeDefined()
127
- // Elysia apps have these methods
128
- expect(typeof app.get).toBe('function')
129
- expect(typeof app.post).toBe('function')
130
- expect(typeof app.listen).toBe('function')
131
- })
132
- })
133
-
134
- describe('getContext', () => {
135
- it('should return framework context', () => {
136
- const context = framework.getContext()
137
-
138
- expect(context).toBeDefined()
139
- expect(context.config).toBeDefined()
140
- expect(typeof context.isDevelopment).toBe('boolean')
141
- expect(typeof context.isProduction).toBe('boolean')
142
- })
143
- })
144
- })
@@ -1,268 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import { loggerPlugin } from '@/core/server/plugins/logger'
3
- import type { FluxStackContext } from '@/core/types'
4
-
5
- describe('Logger Plugin', () => {
6
- let mockContext: FluxStackContext
7
- let mockApp: any
8
-
9
- beforeEach(() => {
10
- vi.clearAllMocks()
11
-
12
- mockContext = {
13
- config: {
14
- port: 3000,
15
- vitePort: 5173,
16
- clientPath: 'app/client',
17
- apiPrefix: '/api',
18
- cors: {
19
- origins: ['http://localhost:5173'],
20
- methods: ['GET', 'POST'],
21
- headers: ['Content-Type']
22
- },
23
- build: {
24
- outDir: 'dist',
25
- target: 'es2020'
26
- }
27
- },
28
- isDevelopment: true,
29
- isProduction: false,
30
- envConfig: {}
31
- } as FluxStackContext
32
-
33
- mockApp = {
34
- onRequest: vi.fn(),
35
- onResponse: vi.fn(),
36
- onError: vi.fn(),
37
- use: vi.fn()
38
- }
39
- })
40
-
41
- describe('Plugin Setup', () => {
42
- it('should have correct plugin name', () => {
43
- expect(loggerPlugin.name).toBe('logger')
44
- })
45
-
46
- it('should have setup function', () => {
47
- expect(typeof loggerPlugin.setup).toBe('function')
48
- })
49
-
50
- it('should setup logger middleware', () => {
51
- loggerPlugin.setup(mockContext, mockApp)
52
-
53
- // Should register onRequest, onResponse, and onError handlers
54
- expect(mockApp.onRequest).toHaveBeenCalledWith(expect.any(Function))
55
- expect(mockApp.onResponse).toHaveBeenCalledWith(expect.any(Function))
56
- expect(mockApp.onError).toHaveBeenCalledWith(expect.any(Function))
57
- })
58
- })
59
-
60
- describe('Request Logging', () => {
61
- it('should log request details', () => {
62
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
63
-
64
- loggerPlugin.setup(mockContext, mockApp)
65
-
66
- // Get the onRequest handler
67
- const onRequestHandler = mockApp.onRequest.mock.calls[0][0]
68
-
69
- const mockRequest = new Request('http://localhost:3000/api/users', {
70
- method: 'GET',
71
- headers: {
72
- 'user-agent': 'test-agent',
73
- 'accept': 'application/json'
74
- }
75
- })
76
-
77
- const mockContext = {
78
- request: mockRequest,
79
- set: {}
80
- }
81
-
82
- onRequestHandler(mockContext)
83
-
84
- expect(consoleSpy).toHaveBeenCalledWith(
85
- expect.stringContaining('📥'),
86
- expect.stringContaining('GET'),
87
- expect.stringContaining('/api/users')
88
- )
89
-
90
- consoleSpy.mockRestore()
91
- })
92
-
93
- it('should log POST requests with different styling', () => {
94
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
95
-
96
- loggerPlugin.setup(mockContext, mockApp)
97
-
98
- const onRequestHandler = mockApp.onRequest.mock.calls[0][0]
99
-
100
- const mockRequest = new Request('http://localhost:3000/api/users', {
101
- method: 'POST',
102
- headers: {
103
- 'content-type': 'application/json'
104
- }
105
- })
106
-
107
- const mockContext = {
108
- request: mockRequest,
109
- set: {}
110
- }
111
-
112
- onRequestHandler(mockContext)
113
-
114
- expect(consoleSpy).toHaveBeenCalledWith(
115
- expect.stringContaining('📥'),
116
- expect.stringContaining('POST'),
117
- expect.stringContaining('/api/users')
118
- )
119
-
120
- consoleSpy.mockRestore()
121
- })
122
- })
123
-
124
- describe('Response Logging', () => {
125
- it('should log successful responses', () => {
126
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
127
-
128
- loggerPlugin.setup(mockContext, mockApp)
129
-
130
- const onResponseHandler = mockApp.onResponse.mock.calls[0][0]
131
-
132
- const mockRequest = new Request('http://localhost:3000/api/users', {
133
- method: 'GET'
134
- })
135
-
136
- const mockResponse = new Response('{"users": []}', {
137
- status: 200,
138
- statusText: 'OK',
139
- headers: {
140
- 'content-type': 'application/json'
141
- }
142
- })
143
-
144
- const mockContext = {
145
- request: mockRequest,
146
- response: mockResponse,
147
- set: { status: 200 }
148
- }
149
-
150
- onResponseHandler(mockContext)
151
-
152
- expect(consoleSpy).toHaveBeenCalledWith(
153
- expect.stringContaining('📤'),
154
- expect.stringContaining('GET'),
155
- expect.stringContaining('/api/users'),
156
- expect.stringContaining('200')
157
- )
158
-
159
- consoleSpy.mockRestore()
160
- })
161
-
162
- it('should log error responses differently', () => {
163
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
164
-
165
- loggerPlugin.setup(mockContext, mockApp)
166
-
167
- const onResponseHandler = mockApp.onResponse.mock.calls[0][0]
168
-
169
- const mockRequest = new Request('http://localhost:3000/api/users/999', {
170
- method: 'GET'
171
- })
172
-
173
- const mockResponse = new Response('{"error": "Not found"}', {
174
- status: 404,
175
- statusText: 'Not Found'
176
- })
177
-
178
- const mockContext = {
179
- request: mockRequest,
180
- response: mockResponse,
181
- set: { status: 404 }
182
- }
183
-
184
- onResponseHandler(mockContext)
185
-
186
- expect(consoleSpy).toHaveBeenCalledWith(
187
- expect.stringContaining('📤'),
188
- expect.stringContaining('GET'),
189
- expect.stringContaining('/api/users/999'),
190
- expect.stringContaining('404')
191
- )
192
-
193
- consoleSpy.mockRestore()
194
- })
195
- })
196
-
197
- describe('Error Logging', () => {
198
- it('should log errors with stack trace', () => {
199
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
200
-
201
- loggerPlugin.setup(mockContext, mockApp)
202
-
203
- const onErrorHandler = mockApp.onError.mock.calls[0][0]
204
-
205
- const mockError = new Error('Test error')
206
- const mockRequest = new Request('http://localhost:3000/api/test')
207
-
208
- const mockContext = {
209
- error: mockError,
210
- request: mockRequest,
211
- set: {}
212
- }
213
-
214
- onErrorHandler(mockContext)
215
-
216
- expect(consoleSpy).toHaveBeenCalledWith(
217
- expect.stringContaining('❌ Error:'),
218
- expect.stringContaining('Test error')
219
- )
220
-
221
- consoleSpy.mockRestore()
222
- })
223
-
224
- it('should handle errors without stack trace', () => {
225
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
226
-
227
- loggerPlugin.setup(mockContext, mockApp)
228
-
229
- const onErrorHandler = mockApp.onError.mock.calls[0][0]
230
-
231
- const mockError = { message: 'Simple error' }
232
- const mockRequest = new Request('http://localhost:3000/api/test')
233
-
234
- const mockContext = {
235
- error: mockError,
236
- request: mockRequest,
237
- set: {}
238
- }
239
-
240
- onErrorHandler(mockContext)
241
-
242
- expect(consoleSpy).toHaveBeenCalledWith(
243
- expect.stringContaining('❌ Error:'),
244
- expect.stringContaining('Simple error')
245
- )
246
-
247
- consoleSpy.mockRestore()
248
- })
249
- })
250
-
251
- describe('Development vs Production', () => {
252
- it('should work in production mode', () => {
253
- const productionContext = {
254
- ...mockContext,
255
- isDevelopment: false,
256
- isProduction: true
257
- }
258
-
259
- expect(() => {
260
- loggerPlugin.setup(productionContext, mockApp)
261
- }).not.toThrow()
262
-
263
- expect(mockApp.onRequest).toHaveBeenCalled()
264
- expect(mockApp.onResponse).toHaveBeenCalled()
265
- expect(mockApp.onError).toHaveBeenCalled()
266
- })
267
- })
268
- })
@@ -1,188 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
-
3
- // Mock global fetch before any other imports
4
- Object.defineProperty(global, 'fetch', {
5
- value: vi.fn(),
6
- writable: true,
7
- configurable: true
8
- })
9
- import { vitePlugin } from '@/core/plugins/built-in/vite'
10
- import type { PluginContext } from '@/core/types'
11
-
12
- // Remove duplicate global fetch assignment as it's now set above
13
-
14
- describe.skip('Vite Plugin', () => {
15
- let mockContext: PluginContext
16
- let mockApp: any
17
-
18
- beforeEach(() => {
19
- vi.clearAllMocks()
20
- vi.clearAllTimers()
21
- vi.useFakeTimers()
22
-
23
- mockContext = {
24
- config: {
25
- server: { port: 3000, host: 'localhost', apiPrefix: '/api', cors: { origins: [], methods: [], headers: [] }, middleware: [] },
26
- client: { port: 5173, proxy: { target: 'http://localhost:3000' }, build: { outDir: 'dist', target: 'es2020', sourceMaps: true, minify: false } },
27
- app: { name: 'test', version: '1.0.0' }
28
- },
29
- logger: { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), child: vi.fn(), time: vi.fn(), timeEnd: vi.fn(), request: vi.fn() },
30
- app: mockApp,
31
- utils: {
32
- isDevelopment: vi.fn(() => true),
33
- isProduction: vi.fn(() => false),
34
- createTimer: vi.fn(),
35
- formatBytes: vi.fn(),
36
- getEnvironment: vi.fn(() => 'test'),
37
- createHash: vi.fn(),
38
- deepMerge: vi.fn(),
39
- validateSchema: vi.fn()
40
- }
41
- } as any
42
-
43
- mockApp = {
44
- get: vi.fn(),
45
- post: vi.fn(),
46
- use: vi.fn()
47
- }
48
- })
49
-
50
- afterEach(() => {
51
- vi.useRealTimers()
52
- })
53
-
54
- describe('Development Mode', () => {
55
- it('should set up plugin in development mode', async () => {
56
- await vitePlugin.setup!(mockContext)
57
-
58
- expect(mockContext.logger.info).toHaveBeenCalledWith('Setting up Vite integration on localhost:5173')
59
- })
60
-
61
- it('should check for Vite after timeout', async () => {
62
- // Mock successful Vite check
63
- vi.mocked(fetch).mockResolvedValueOnce({
64
- status: 200,
65
- ok: true
66
- } as Response)
67
-
68
- await vitePlugin.setup!(mockContext)
69
-
70
- // Fast-forward timers to trigger the setTimeout
71
- vi.advanceTimersByTime(2000)
72
-
73
- // Wait for the async operation to complete
74
- await vi.runAllTimersAsync()
75
-
76
- expect(fetch).toHaveBeenCalledWith('http://localhost:5173', {
77
- signal: expect.any(AbortSignal)
78
- })
79
-
80
- expect(mockContext.logger.info).toHaveBeenCalledWith('✓ Vite server detected on localhost:5173')
81
- expect(mockContext.logger.info).toHaveBeenCalledWith('Hot reload coordination active')
82
- })
83
-
84
- it('should handle Vite check failure silently', async () => {
85
- // Mock failed Vite check
86
- vi.mocked(fetch).mockRejectedValueOnce(new Error('Connection refused'))
87
-
88
- await vitePlugin.setup!(mockContext)
89
-
90
- // Fast-forward timers
91
- vi.advanceTimersByTime(2000)
92
- await vi.runAllTimersAsync()
93
-
94
- expect(fetch).toHaveBeenCalledWith('http://localhost:5173', {
95
- signal: expect.any(AbortSignal)
96
- })
97
-
98
- // Should not log success messages when Vite is not running
99
- expect(mockContext.logger.info).not.toHaveBeenCalledWith('✓ Vite server detected on localhost:5173')
100
- })
101
-
102
- it('should use custom vite port from context', async () => {
103
- const customContext = {
104
- ...mockContext,
105
- config: {
106
- ...mockContext.config,
107
- client: { ...mockContext.config.client, port: 3001 }
108
- }
109
- }
110
-
111
- vi.mocked(fetch).mockResolvedValueOnce({
112
- status: 200,
113
- ok: true
114
- } as Response)
115
-
116
- await vitePlugin.setup!(customContext)
117
-
118
- expect(customContext.logger.info).toHaveBeenCalledWith('Setting up Vite integration on localhost:3001')
119
-
120
- vi.advanceTimersByTime(2000)
121
- await vi.runAllTimersAsync()
122
-
123
- expect(fetch).toHaveBeenCalledWith('http://localhost:3001', {
124
- signal: expect.any(AbortSignal)
125
- })
126
- })
127
- })
128
-
129
- describe('Production Mode', () => {
130
- it('should skip plugin setup in production mode', async () => {
131
- const productionContext = {
132
- ...mockContext,
133
- utils: {
134
- ...mockContext.utils,
135
- isDevelopment: vi.fn(() => false),
136
- isProduction: vi.fn(() => true)
137
- }
138
- }
139
-
140
- await vitePlugin.setup!(productionContext)
141
-
142
- expect(productionContext.logger.info).not.toHaveBeenCalled()
143
- expect(fetch).not.toHaveBeenCalled()
144
- })
145
- })
146
-
147
- describe('Plugin Properties', () => {
148
- it('should have correct plugin name', () => {
149
- expect(vitePlugin.name).toBe('vite')
150
- })
151
-
152
- it('should have setup function', () => {
153
- expect(typeof vitePlugin.setup).toBe('function')
154
- })
155
- })
156
-
157
- describe('checkViteRunning function', () => {
158
- it('should return true for successful connection', async () => {
159
- vi.mocked(fetch).mockResolvedValueOnce({
160
- status: 200,
161
- ok: true
162
- } as Response)
163
-
164
- // We need to access the checkViteRunning function
165
- // Since it's not exported, we'll test it indirectly through the plugin
166
- await vitePlugin.setup!(mockContext)
167
- vi.advanceTimersByTime(2000)
168
- await vi.runAllTimersAsync()
169
-
170
- expect(mockContext.logger.info).toHaveBeenCalledWith('✓ Vite server detected on localhost:5173')
171
- })
172
-
173
- it('should return false for connection timeout', async () => {
174
- vi.mocked(fetch).mockImplementationOnce(() =>
175
- new Promise((_, reject) => {
176
- setTimeout(() => reject(new Error('timeout')), 1500)
177
- })
178
- )
179
-
180
- await vitePlugin.setup!(mockContext)
181
- vi.advanceTimersByTime(2000)
182
- await vi.runAllTimersAsync()
183
-
184
- // Should not show success message when timeout occurs
185
- expect(mockContext.logger.info).not.toHaveBeenCalledWith('✓ Vite server detected on localhost:5173')
186
- })
187
- })
188
- })