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,372 +0,0 @@
1
- /**
2
- * Tests for Environment Variable Type Conversion Utilities
3
- * Tests edge cases and type conversion robustness
4
- */
5
-
6
- import { describe, test, expect } from 'vitest'
7
- import { EnvConverter } from '../env'
8
-
9
- describe('EnvConverter Edge Cases and Robustness', () => {
10
- describe('toNumber edge cases', () => {
11
- test('handles various number formats correctly', () => {
12
- // Basic cases
13
- expect(EnvConverter.toNumber('42', 0)).toBe(42)
14
- expect(EnvConverter.toNumber('-123', 0)).toBe(-123)
15
- expect(EnvConverter.toNumber('0', 42)).toBe(0)
16
-
17
- // Edge cases
18
- expect(EnvConverter.toNumber('00000123', 0)).toBe(123)
19
- expect(EnvConverter.toNumber('+456', 0)).toBe(456)
20
- expect(EnvConverter.toNumber(' 789 ', 0)).toBe(789) // With whitespace
21
-
22
- // Hex and octal (parseInt with base 10 behavior)
23
- expect(EnvConverter.toNumber('0x10', 0)).toBe(0) // parseInt with base 10 doesn't parse hex
24
- expect(EnvConverter.toNumber('0o10', 0)).toBe(0) // parseInt doesn't handle 0o prefix
25
- expect(EnvConverter.toNumber('010', 0)).toBe(10) // Treated as decimal, not octal
26
-
27
- // Invalid cases
28
- expect(EnvConverter.toNumber('abc', 42)).toBe(42)
29
- expect(EnvConverter.toNumber('123abc', 42)).toBe(123) // parseInt stops at first non-digit
30
- expect(EnvConverter.toNumber('', 42)).toBe(42)
31
- expect(EnvConverter.toNumber(' ', 42)).toBe(42)
32
- expect(EnvConverter.toNumber('Infinity', 42)).toBe(42)
33
- expect(EnvConverter.toNumber('NaN', 42)).toBe(42)
34
- expect(EnvConverter.toNumber(undefined, 42)).toBe(42)
35
- })
36
-
37
- test('handles floating point strings (parseInt behavior)', () => {
38
- // parseInt truncates to integer
39
- expect(EnvConverter.toNumber('12.34', 0)).toBe(12)
40
- expect(EnvConverter.toNumber('56.78', 0)).toBe(56)
41
- expect(EnvConverter.toNumber('.123', 0)).toBe(0) // parseInt behavior with leading dot
42
- expect(EnvConverter.toNumber('9.', 0)).toBe(9)
43
- })
44
-
45
- test('handles extreme values', () => {
46
- expect(EnvConverter.toNumber('999999999999999', 0)).toBe(999999999999999)
47
- expect(EnvConverter.toNumber('-999999999999999', 0)).toBe(-999999999999999)
48
- expect(EnvConverter.toNumber('1e10', 0)).toBe(1) // parseInt stops at 'e'
49
- })
50
- })
51
-
52
- describe('toBoolean edge cases', () => {
53
- test('handles various truthy representations', () => {
54
- // Standard truthy values
55
- expect(EnvConverter.toBoolean('true', false)).toBe(true)
56
- expect(EnvConverter.toBoolean('1', false)).toBe(true)
57
- expect(EnvConverter.toBoolean('yes', false)).toBe(true)
58
- expect(EnvConverter.toBoolean('on', false)).toBe(true)
59
-
60
- // Case variations
61
- expect(EnvConverter.toBoolean('TRUE', false)).toBe(true)
62
- expect(EnvConverter.toBoolean('True', false)).toBe(true)
63
- expect(EnvConverter.toBoolean('YES', false)).toBe(true)
64
- expect(EnvConverter.toBoolean('Yes', false)).toBe(true)
65
- expect(EnvConverter.toBoolean('ON', false)).toBe(true)
66
- expect(EnvConverter.toBoolean('On', false)).toBe(true)
67
-
68
- // With whitespace
69
- expect(EnvConverter.toBoolean(' true ', false)).toBe(false) // No trim in current implementation
70
- expect(EnvConverter.toBoolean(' 1 ', false)).toBe(false)
71
- })
72
-
73
- test('handles various falsy representations', () => {
74
- // Standard falsy values
75
- expect(EnvConverter.toBoolean('false', true)).toBe(false)
76
- expect(EnvConverter.toBoolean('0', true)).toBe(false)
77
- expect(EnvConverter.toBoolean('no', true)).toBe(false)
78
- expect(EnvConverter.toBoolean('off', true)).toBe(false)
79
-
80
- // Any other string is falsy
81
- expect(EnvConverter.toBoolean('maybe', true)).toBe(false)
82
- expect(EnvConverter.toBoolean('2', true)).toBe(false)
83
- expect(EnvConverter.toBoolean('anything', true)).toBe(false)
84
- expect(EnvConverter.toBoolean('', true)).toBe(false)
85
- })
86
-
87
- test('handles edge cases', () => {
88
- expect(EnvConverter.toBoolean(undefined, true)).toBe(true)
89
- expect(EnvConverter.toBoolean(undefined, false)).toBe(false)
90
- })
91
- })
92
-
93
- describe('toArray edge cases', () => {
94
- test('handles various delimiter scenarios', () => {
95
- // Basic cases
96
- expect(EnvConverter.toArray('a,b,c')).toEqual(['a', 'b', 'c'])
97
- expect(EnvConverter.toArray('single')).toEqual(['single'])
98
-
99
- // Whitespace handling
100
- expect(EnvConverter.toArray('a, b , c')).toEqual(['a', 'b', 'c'])
101
- expect(EnvConverter.toArray(' a , b , c ')).toEqual(['a', 'b', 'c'])
102
-
103
- // Empty values
104
- expect(EnvConverter.toArray('a,,c')).toEqual(['a', 'c'])
105
- expect(EnvConverter.toArray(',a,b,')).toEqual(['a', 'b'])
106
- expect(EnvConverter.toArray(',,,')).toEqual([])
107
-
108
- // Special characters
109
- expect(EnvConverter.toArray('a\\,b,c')).toEqual(['a\\', 'b', 'c']) // No escape handling
110
- expect(EnvConverter.toArray('a"b,c')).toEqual(['a"b', 'c'])
111
- expect(EnvConverter.toArray("a'b,c")).toEqual(["a'b", 'c'])
112
- })
113
-
114
- test('handles empty and undefined inputs', () => {
115
- expect(EnvConverter.toArray('')).toEqual([])
116
- expect(EnvConverter.toArray(undefined)).toEqual([])
117
- expect(EnvConverter.toArray(undefined, ['default'])).toEqual(['default'])
118
- })
119
-
120
- test('handles URLs and complex strings', () => {
121
- const urls = 'http://localhost:3000,https://example.com:8080,ftp://ftp.example.com'
122
- expect(EnvConverter.toArray(urls)).toEqual([
123
- 'http://localhost:3000',
124
- 'https://example.com:8080',
125
- 'ftp://ftp.example.com'
126
- ])
127
-
128
- const methods = 'GET,POST,PUT,DELETE,PATCH,OPTIONS,HEAD'
129
- expect(EnvConverter.toArray(methods)).toEqual([
130
- 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'
131
- ])
132
- })
133
- })
134
-
135
- describe('toLogLevel edge cases', () => {
136
- test('handles case variations', () => {
137
- expect(EnvConverter.toLogLevel('DEBUG', 'info')).toBe('debug')
138
- expect(EnvConverter.toLogLevel('Info', 'debug')).toBe('info')
139
- expect(EnvConverter.toLogLevel('WARN', 'info')).toBe('warn')
140
- expect(EnvConverter.toLogLevel('Error', 'info')).toBe('error')
141
- })
142
-
143
- test('handles invalid levels', () => {
144
- expect(EnvConverter.toLogLevel('verbose', 'info')).toBe('info')
145
- expect(EnvConverter.toLogLevel('trace', 'warn')).toBe('warn')
146
- expect(EnvConverter.toLogLevel('critical', 'error')).toBe('error')
147
- expect(EnvConverter.toLogLevel('', 'debug')).toBe('debug')
148
- expect(EnvConverter.toLogLevel('123', 'info')).toBe('info')
149
- })
150
-
151
- test('handles whitespace and special characters', () => {
152
- expect(EnvConverter.toLogLevel(' debug ', 'info')).toBe('info') // No trim
153
- expect(EnvConverter.toLogLevel('debug\n', 'info')).toBe('info')
154
- expect(EnvConverter.toLogLevel('de-bug', 'info')).toBe('info')
155
- })
156
- })
157
-
158
- describe('toBuildTarget edge cases', () => {
159
- test('handles case variations', () => {
160
- expect(EnvConverter.toBuildTarget('BUN', 'node')).toBe('bun')
161
- expect(EnvConverter.toBuildTarget('Node', 'bun')).toBe('node')
162
- expect(EnvConverter.toBuildTarget('DOCKER', 'bun')).toBe('docker')
163
- })
164
-
165
- test('handles invalid targets', () => {
166
- expect(EnvConverter.toBuildTarget('webpack', 'bun')).toBe('bun')
167
- expect(EnvConverter.toBuildTarget('rollup', 'node')).toBe('node')
168
- expect(EnvConverter.toBuildTarget('vite', 'docker')).toBe('docker')
169
- expect(EnvConverter.toBuildTarget('', 'bun')).toBe('bun')
170
- })
171
-
172
- test('handles similar but invalid targets', () => {
173
- expect(EnvConverter.toBuildTarget('nodejs', 'bun')).toBe('bun')
174
- expect(EnvConverter.toBuildTarget('bunjs', 'node')).toBe('node')
175
- expect(EnvConverter.toBuildTarget('container', 'bun')).toBe('bun')
176
- })
177
- })
178
-
179
- describe('toLogFormat edge cases', () => {
180
- test('handles case variations', () => {
181
- expect(EnvConverter.toLogFormat('JSON', 'pretty')).toBe('json')
182
- expect(EnvConverter.toLogFormat('Pretty', 'json')).toBe('pretty')
183
- expect(EnvConverter.toLogFormat('PRETTY', 'json')).toBe('pretty')
184
- })
185
-
186
- test('handles invalid formats', () => {
187
- expect(EnvConverter.toLogFormat('text', 'json')).toBe('json')
188
- expect(EnvConverter.toLogFormat('yaml', 'pretty')).toBe('pretty')
189
- expect(EnvConverter.toLogFormat('structured', 'json')).toBe('json')
190
- expect(EnvConverter.toLogFormat('', 'pretty')).toBe('pretty')
191
- })
192
- })
193
-
194
- describe('toObject edge cases', () => {
195
- test('handles valid JSON variations', () => {
196
- expect(EnvConverter.toObject('{"key":"value"}', {})).toEqual({ key: 'value' })
197
- expect(EnvConverter.toObject('{"nested":{"key":"value"}}', {})).toEqual({
198
- nested: { key: 'value' }
199
- })
200
- expect(EnvConverter.toObject('[1,2,3]', {})).toEqual([1, 2, 3])
201
- expect(EnvConverter.toObject('null', {})).toBe(null)
202
- expect(EnvConverter.toObject('true', {})).toBe(true)
203
- expect(EnvConverter.toObject('42', {})).toBe(42)
204
- expect(EnvConverter.toObject('"string"', {})).toBe('string')
205
- })
206
-
207
- test('handles malformed JSON', () => {
208
- const defaultValue = { default: true }
209
-
210
- expect(EnvConverter.toObject('{key:"value"}', defaultValue)).toBe(defaultValue) // Missing quotes
211
- expect(EnvConverter.toObject('{"key":value}', defaultValue)).toBe(defaultValue) // Unquoted value
212
- expect(EnvConverter.toObject('{key:value}', defaultValue)).toBe(defaultValue) // No quotes
213
- expect(EnvConverter.toObject('{"key":"value",}', defaultValue)).toBe(defaultValue) // Trailing comma
214
- expect(EnvConverter.toObject('{', defaultValue)).toBe(defaultValue) // Incomplete
215
- expect(EnvConverter.toObject('not json at all', defaultValue)).toBe(defaultValue)
216
- })
217
-
218
- test('handles edge JSON cases', () => {
219
- expect(EnvConverter.toObject('{}', { default: true })).toEqual({})
220
- expect(EnvConverter.toObject('[]', { default: true })).toEqual([])
221
- expect(EnvConverter.toObject('""', { default: true })).toBe('')
222
- expect(EnvConverter.toObject('0', { default: true })).toBe(0)
223
- expect(EnvConverter.toObject('false', { default: true })).toBe(false)
224
- })
225
-
226
- test('handles complex nested objects', () => {
227
- const complexJson = JSON.stringify({
228
- server: {
229
- port: 3000,
230
- host: 'localhost',
231
- options: {
232
- cors: true,
233
- compression: false,
234
- middleware: ['auth', 'logging']
235
- }
236
- },
237
- database: {
238
- url: 'postgresql://localhost:5432/db',
239
- pool: { min: 2, max: 10 }
240
- }
241
- })
242
-
243
- const result = EnvConverter.toObject(complexJson, {})
244
- expect(result).toEqual({
245
- server: {
246
- port: 3000,
247
- host: 'localhost',
248
- options: {
249
- cors: true,
250
- compression: false,
251
- middleware: ['auth', 'logging']
252
- }
253
- },
254
- database: {
255
- url: 'postgresql://localhost:5432/db',
256
- pool: { min: 2, max: 10 }
257
- }
258
- })
259
- })
260
-
261
- test('handles undefined and empty inputs', () => {
262
- const defaultValue = { default: true }
263
- expect(EnvConverter.toObject(undefined, defaultValue)).toBe(defaultValue)
264
- expect(EnvConverter.toObject('', defaultValue)).toBe(defaultValue)
265
- })
266
- })
267
-
268
- describe('Conversion consistency', () => {
269
- test('maintains type safety across conversions', () => {
270
- // Number conversions should always return numbers or defaults
271
- const numResult = EnvConverter.toNumber('invalid', 42)
272
- expect(typeof numResult).toBe('number')
273
- expect(numResult).toBe(42)
274
-
275
- // Boolean conversions should always return booleans
276
- const boolResult = EnvConverter.toBoolean('maybe', true)
277
- expect(typeof boolResult).toBe('boolean')
278
-
279
- // Array conversions should always return arrays
280
- const arrayResult = EnvConverter.toArray('a,b,c')
281
- expect(Array.isArray(arrayResult)).toBe(true)
282
-
283
- // String enums should return valid enum values or defaults
284
- const logLevelResult = EnvConverter.toLogLevel('invalid', 'info')
285
- expect(['debug', 'info', 'warn', 'error']).toContain(logLevelResult)
286
- })
287
-
288
- test('handles null and undefined consistently', () => {
289
- expect(EnvConverter.toNumber(undefined, 42)).toBe(42)
290
- expect(EnvConverter.toBoolean(undefined, true)).toBe(true)
291
- expect(EnvConverter.toArray(undefined)).toEqual([])
292
- expect(EnvConverter.toLogLevel(undefined, 'info')).toBe('info')
293
- expect(EnvConverter.toBuildTarget(undefined, 'bun')).toBe('bun')
294
- expect(EnvConverter.toLogFormat(undefined, 'pretty')).toBe('pretty')
295
- expect(EnvConverter.toObject(undefined, {})).toEqual({})
296
- })
297
- })
298
-
299
- describe('Real-world environment variable scenarios', () => {
300
- test('handles PORT environment variable edge cases', () => {
301
- // Common port scenarios
302
- expect(EnvConverter.toNumber('3000', 8080)).toBe(3000)
303
- expect(EnvConverter.toNumber('0', 8080)).toBe(0) // Dynamic port
304
- expect(EnvConverter.toNumber('80', 8080)).toBe(80)
305
- expect(EnvConverter.toNumber('443', 8080)).toBe(443)
306
- expect(EnvConverter.toNumber('8080', 3000)).toBe(8080)
307
-
308
- // Invalid port values
309
- expect(EnvConverter.toNumber('port', 3000)).toBe(3000)
310
- expect(EnvConverter.toNumber('-1', 3000)).toBe(-1) // Negative (invalid but parsed)
311
- expect(EnvConverter.toNumber('70000', 3000)).toBe(70000) // Out of range but parsed
312
- })
313
-
314
- test('handles CORS_ORIGINS environment variable', () => {
315
- // Single origin
316
- expect(EnvConverter.toArray('http://localhost:3000')).toEqual(['http://localhost:3000'])
317
-
318
- // Multiple origins
319
- expect(EnvConverter.toArray('http://localhost:3000,https://example.com')).toEqual([
320
- 'http://localhost:3000',
321
- 'https://example.com'
322
- ])
323
-
324
- // With ports and paths
325
- expect(EnvConverter.toArray('http://localhost:3000,https://example.com:8080/app')).toEqual([
326
- 'http://localhost:3000',
327
- 'https://example.com:8080/app'
328
- ])
329
-
330
- // Wildcard
331
- expect(EnvConverter.toArray('*')).toEqual(['*'])
332
- })
333
-
334
- test('handles boolean flags from different tools', () => {
335
- // Docker-style
336
- expect(EnvConverter.toBoolean('true', false)).toBe(true)
337
- expect(EnvConverter.toBoolean('false', true)).toBe(false)
338
-
339
- // Shell-style
340
- expect(EnvConverter.toBoolean('1', false)).toBe(true)
341
- expect(EnvConverter.toBoolean('0', true)).toBe(false)
342
-
343
- // Human-readable
344
- expect(EnvConverter.toBoolean('yes', false)).toBe(true)
345
- expect(EnvConverter.toBoolean('no', true)).toBe(false)
346
- expect(EnvConverter.toBoolean('on', false)).toBe(true)
347
- expect(EnvConverter.toBoolean('off', true)).toBe(false)
348
- })
349
-
350
- test('handles complex JSON configurations', () => {
351
- // Plugin configuration
352
- const pluginConfig = JSON.stringify({
353
- enabled: true,
354
- options: {
355
- timeout: 5000,
356
- retries: 3,
357
- endpoints: ['api', 'webhook']
358
- }
359
- })
360
-
361
- const result = EnvConverter.toObject(pluginConfig, {})
362
- expect(result).toEqual({
363
- enabled: true,
364
- options: {
365
- timeout: 5000,
366
- retries: 3,
367
- endpoints: ['api', 'webhook']
368
- }
369
- })
370
- })
371
- })
372
- })