create-fluxstack 1.10.1 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/.dockerignore +1 -2
  2. package/Dockerfile +8 -8
  3. package/LLMD/INDEX.md +64 -0
  4. package/LLMD/MAINTENANCE.md +197 -0
  5. package/LLMD/MIGRATION.md +156 -0
  6. package/LLMD/config/.gitkeep +1 -0
  7. package/LLMD/config/declarative-system.md +268 -0
  8. package/LLMD/config/environment-vars.md +327 -0
  9. package/LLMD/config/runtime-reload.md +401 -0
  10. package/LLMD/core/.gitkeep +1 -0
  11. package/LLMD/core/build-system.md +599 -0
  12. package/LLMD/core/framework-lifecycle.md +229 -0
  13. package/LLMD/core/plugin-system.md +451 -0
  14. package/LLMD/patterns/.gitkeep +1 -0
  15. package/LLMD/patterns/anti-patterns.md +297 -0
  16. package/LLMD/patterns/project-structure.md +264 -0
  17. package/LLMD/patterns/type-safety.md +440 -0
  18. package/LLMD/reference/.gitkeep +1 -0
  19. package/LLMD/reference/cli-commands.md +250 -0
  20. package/LLMD/reference/plugin-hooks.md +357 -0
  21. package/LLMD/reference/routing.md +39 -0
  22. package/LLMD/reference/troubleshooting.md +364 -0
  23. package/LLMD/resources/.gitkeep +1 -0
  24. package/LLMD/resources/controllers.md +465 -0
  25. package/LLMD/resources/live-components.md +703 -0
  26. package/LLMD/resources/live-rooms.md +482 -0
  27. package/LLMD/resources/live-upload.md +130 -0
  28. package/LLMD/resources/plugins-external.md +617 -0
  29. package/LLMD/resources/routes-eden.md +254 -0
  30. package/README.md +37 -17
  31. package/app/client/index.html +0 -1
  32. package/app/client/src/App.tsx +107 -150
  33. package/app/client/src/components/AppLayout.tsx +68 -0
  34. package/app/client/src/components/BackButton.tsx +13 -0
  35. package/app/client/src/components/DemoPage.tsx +20 -0
  36. package/app/client/src/components/LiveUploadWidget.tsx +204 -0
  37. package/app/client/src/lib/eden-api.ts +85 -60
  38. package/app/client/src/live/ChatDemo.tsx +107 -0
  39. package/app/client/src/live/CounterDemo.tsx +206 -0
  40. package/app/client/src/live/FormDemo.tsx +119 -0
  41. package/app/client/src/live/RoomChatDemo.tsx +161 -0
  42. package/app/client/src/live/UploadDemo.tsx +21 -0
  43. package/app/client/src/main.tsx +4 -1
  44. package/app/client/src/pages/ApiTestPage.tsx +108 -0
  45. package/app/client/src/pages/HomePage.tsx +76 -0
  46. package/app/server/app.ts +1 -4
  47. package/app/server/controllers/users.controller.ts +36 -44
  48. package/app/server/index.ts +25 -35
  49. package/app/server/live/LiveChat.ts +77 -0
  50. package/app/server/live/LiveCounter.ts +67 -0
  51. package/app/server/live/LiveForm.ts +63 -0
  52. package/app/server/live/LiveLocalCounter.ts +32 -0
  53. package/app/server/live/LiveRoomChat.ts +127 -0
  54. package/app/server/live/LiveUpload.ts +81 -0
  55. package/app/server/routes/index.ts +3 -1
  56. package/app/server/routes/room.routes.ts +117 -0
  57. package/app/server/routes/users.routes.ts +35 -27
  58. package/app/shared/types/index.ts +14 -2
  59. package/config/app.config.ts +2 -62
  60. package/config/client.config.ts +2 -95
  61. package/config/database.config.ts +2 -99
  62. package/config/fluxstack.config.ts +25 -45
  63. package/config/index.ts +57 -38
  64. package/config/monitoring.config.ts +2 -114
  65. package/config/plugins.config.ts +2 -80
  66. package/config/server.config.ts +2 -68
  67. package/config/services.config.ts +2 -130
  68. package/config/system/app.config.ts +29 -0
  69. package/config/system/build.config.ts +49 -0
  70. package/config/system/client.config.ts +68 -0
  71. package/config/system/database.config.ts +17 -0
  72. package/config/system/fluxstack.config.ts +114 -0
  73. package/config/{logger.config.ts → system/logger.config.ts} +3 -1
  74. package/config/system/monitoring.config.ts +114 -0
  75. package/config/system/plugins.config.ts +84 -0
  76. package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
  77. package/config/system/server.config.ts +68 -0
  78. package/config/system/services.config.ts +46 -0
  79. package/config/{system.config.ts → system/system.config.ts} +1 -1
  80. package/core/build/flux-plugins-generator.ts +325 -325
  81. package/core/build/index.ts +39 -27
  82. package/core/build/live-components-generator.ts +3 -3
  83. package/core/build/optimizer.ts +235 -235
  84. package/core/cli/command-registry.ts +6 -4
  85. package/core/cli/commands/build.ts +79 -0
  86. package/core/cli/commands/create.ts +54 -0
  87. package/core/cli/commands/dev.ts +101 -0
  88. package/core/cli/commands/help.ts +34 -0
  89. package/core/cli/commands/index.ts +34 -0
  90. package/core/cli/commands/make-plugin.ts +90 -0
  91. package/core/cli/commands/plugin-add.ts +197 -0
  92. package/core/cli/commands/plugin-deps.ts +2 -2
  93. package/core/cli/commands/plugin-list.ts +208 -0
  94. package/core/cli/commands/plugin-remove.ts +170 -0
  95. package/core/cli/generators/component.ts +769 -769
  96. package/core/cli/generators/controller.ts +1 -1
  97. package/core/cli/generators/index.ts +146 -146
  98. package/core/cli/generators/interactive.ts +227 -227
  99. package/core/cli/generators/plugin.ts +2 -2
  100. package/core/cli/generators/prompts.ts +82 -82
  101. package/core/cli/generators/route.ts +6 -6
  102. package/core/cli/generators/service.ts +2 -2
  103. package/core/cli/generators/template-engine.ts +4 -3
  104. package/core/cli/generators/types.ts +2 -2
  105. package/core/cli/generators/utils.ts +191 -191
  106. package/core/cli/index.ts +115 -686
  107. package/core/cli/plugin-discovery.ts +2 -2
  108. package/core/client/LiveComponentsProvider.tsx +60 -8
  109. package/core/client/api/eden.ts +183 -0
  110. package/core/client/api/index.ts +11 -0
  111. package/core/client/components/Live.tsx +104 -0
  112. package/core/client/fluxstack.ts +1 -9
  113. package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
  114. package/core/client/hooks/state-validator.ts +1 -1
  115. package/core/client/hooks/useAuth.ts +48 -48
  116. package/core/client/hooks/useChunkedUpload.ts +85 -35
  117. package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
  118. package/core/client/hooks/useLiveComponent.ts +800 -0
  119. package/core/client/hooks/useLiveUpload.ts +71 -0
  120. package/core/client/hooks/useRoom.ts +409 -0
  121. package/core/client/hooks/useRoomProxy.ts +382 -0
  122. package/core/client/index.ts +17 -68
  123. package/core/client/standalone-entry.ts +8 -0
  124. package/core/client/standalone.ts +74 -53
  125. package/core/client/state/createStore.ts +192 -192
  126. package/core/client/state/index.ts +14 -14
  127. package/core/config/index.ts +70 -291
  128. package/core/config/schema.ts +42 -723
  129. package/core/framework/client.ts +131 -131
  130. package/core/framework/index.ts +7 -7
  131. package/core/framework/server.ts +47 -40
  132. package/core/framework/types.ts +2 -2
  133. package/core/index.ts +23 -4
  134. package/core/live/ComponentRegistry.ts +3 -3
  135. package/core/live/types.ts +77 -0
  136. package/core/plugins/built-in/index.ts +134 -134
  137. package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
  138. package/core/plugins/built-in/live-components/index.ts +1 -1
  139. package/core/plugins/built-in/monitoring/index.ts +111 -47
  140. package/core/plugins/built-in/static/index.ts +1 -1
  141. package/core/plugins/built-in/swagger/index.ts +68 -265
  142. package/core/plugins/built-in/vite/index.ts +85 -185
  143. package/core/plugins/built-in/vite/vite-dev.ts +10 -16
  144. package/core/plugins/config.ts +9 -7
  145. package/core/plugins/dependency-manager.ts +31 -1
  146. package/core/plugins/discovery.ts +19 -7
  147. package/core/plugins/executor.ts +2 -2
  148. package/core/plugins/index.ts +203 -203
  149. package/core/plugins/manager.ts +27 -39
  150. package/core/plugins/module-resolver.ts +19 -8
  151. package/core/plugins/registry.ts +255 -19
  152. package/core/plugins/types.ts +20 -53
  153. package/core/server/framework.ts +66 -43
  154. package/core/server/index.ts +15 -15
  155. package/core/server/live/ComponentRegistry.ts +78 -71
  156. package/core/server/live/FileUploadManager.ts +23 -10
  157. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  158. package/core/server/live/LiveRoomManager.ts +261 -0
  159. package/core/server/live/RoomEventBus.ts +234 -0
  160. package/core/server/live/RoomStateManager.ts +172 -0
  161. package/core/server/live/StateSignature.ts +643 -643
  162. package/core/server/live/WebSocketConnectionManager.ts +30 -19
  163. package/core/server/live/auto-generated-components.ts +21 -9
  164. package/core/server/live/index.ts +14 -0
  165. package/core/server/live/websocket-plugin.ts +214 -67
  166. package/core/server/middleware/elysia-helpers.ts +7 -2
  167. package/core/server/middleware/errorHandling.ts +1 -1
  168. package/core/server/middleware/index.ts +31 -31
  169. package/core/server/plugins/database.ts +180 -180
  170. package/core/server/plugins/static-files-plugin.ts +69 -69
  171. package/core/server/plugins/swagger.ts +1 -1
  172. package/core/server/rooms/RoomBroadcaster.ts +357 -0
  173. package/core/server/rooms/RoomSystem.ts +463 -0
  174. package/core/server/rooms/index.ts +13 -0
  175. package/core/server/services/BaseService.ts +1 -1
  176. package/core/server/services/ServiceContainer.ts +1 -1
  177. package/core/server/services/index.ts +8 -8
  178. package/core/templates/create-project.ts +12 -12
  179. package/core/testing/index.ts +9 -9
  180. package/core/testing/setup.ts +73 -73
  181. package/core/types/api.ts +168 -168
  182. package/core/types/build.ts +219 -219
  183. package/core/types/config.ts +56 -26
  184. package/core/types/index.ts +4 -4
  185. package/core/types/plugin.ts +107 -107
  186. package/core/types/types.ts +353 -14
  187. package/core/utils/build-logger.ts +324 -324
  188. package/core/utils/config-schema.ts +480 -480
  189. package/core/utils/env.ts +2 -8
  190. package/core/utils/errors/codes.ts +114 -114
  191. package/core/utils/errors/handlers.ts +36 -1
  192. package/core/utils/errors/index.ts +49 -5
  193. package/core/utils/errors/middleware.ts +113 -113
  194. package/core/utils/helpers.ts +6 -16
  195. package/core/utils/index.ts +17 -17
  196. package/core/utils/logger/colors.ts +114 -114
  197. package/core/utils/logger/config.ts +13 -9
  198. package/core/utils/logger/formatter.ts +82 -82
  199. package/core/utils/logger/group-logger.ts +101 -101
  200. package/core/utils/logger/index.ts +6 -1
  201. package/core/utils/logger/stack-trace.ts +3 -1
  202. package/core/utils/logger/startup-banner.ts +82 -82
  203. package/core/utils/logger/winston-logger.ts +152 -152
  204. package/core/utils/monitoring/index.ts +211 -211
  205. package/core/utils/sync-version.ts +66 -66
  206. package/core/utils/version.ts +1 -1
  207. package/create-fluxstack.ts +8 -7
  208. package/package.json +12 -13
  209. package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
  210. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  211. package/plugins/crypto-auth/client/components/index.ts +11 -11
  212. package/plugins/crypto-auth/client/index.ts +11 -11
  213. package/plugins/crypto-auth/config/index.ts +1 -1
  214. package/plugins/crypto-auth/index.ts +4 -4
  215. package/plugins/crypto-auth/package.json +65 -65
  216. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  217. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  218. package/plugins/crypto-auth/server/index.ts +21 -21
  219. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
  220. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
  221. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
  222. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
  223. package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
  224. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  225. package/tsconfig.api-strict.json +16 -0
  226. package/tsconfig.json +48 -52
  227. package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
  228. package/types/global.d.ts +29 -29
  229. package/types/vitest.d.ts +8 -8
  230. package/vite.config.ts +38 -62
  231. package/vitest.config.live.ts +10 -9
  232. package/vitest.config.ts +29 -17
  233. package/app/client/README.md +0 -69
  234. package/app/client/SIMPLIFICATION.md +0 -140
  235. package/app/client/frontend-only.ts +0 -12
  236. package/app/client/src/live/FileUploadExample.tsx +0 -359
  237. package/app/client/src/live/MinimalLiveClock.tsx +0 -47
  238. package/app/client/src/live/QuickUploadTest.tsx +0 -193
  239. package/app/client/tsconfig.app.json +0 -45
  240. package/app/client/tsconfig.json +0 -7
  241. package/app/client/zustand-setup.md +0 -65
  242. package/app/server/backend-only.ts +0 -18
  243. package/app/server/live/LiveClockComponent.ts +0 -215
  244. package/app/server/live/LiveFileUploadComponent.ts +0 -77
  245. package/app/server/routes/env-test.ts +0 -110
  246. package/core/client/hooks/index.ts +0 -7
  247. package/core/client/hooks/useHybridLiveComponent.ts +0 -685
  248. package/core/client/hooks/useTypedLiveComponent.ts +0 -133
  249. package/core/client/hooks/useWebSocket.ts +0 -361
  250. package/core/config/env.ts +0 -546
  251. package/core/config/loader.ts +0 -522
  252. package/core/config/runtime-config.ts +0 -327
  253. package/core/config/validator.ts +0 -540
  254. package/core/server/backend-entry.ts +0 -51
  255. package/core/server/standalone.ts +0 -106
  256. package/core/utils/regenerate-files.ts +0 -69
  257. package/fluxstack.config.ts +0 -354
@@ -142,10 +142,15 @@ export function request(method: string, path: string, status?: number, duration?
142
142
 
143
143
  // Color for HTTP method
144
144
  let methodColor = chalk.blue
145
- if (method === 'POST') methodColor = chalk.green
145
+ if (method === 'GET') methodColor = chalk.blue
146
+ else if (method === 'POST') methodColor = chalk.green
146
147
  else if (method === 'PUT') methodColor = chalk.yellow
147
148
  else if (method === 'PATCH') methodColor = chalk.magenta
148
149
  else if (method === 'DELETE') methodColor = chalk.red
150
+ else if (method === 'HEAD') methodColor = chalk.cyan
151
+ else if (method === 'OPTIONS') methodColor = chalk.gray
152
+ else if (method === 'CONNECT') methodColor = chalk.blueBright
153
+ else if (method === 'TRACE') methodColor = chalk.dim
149
154
 
150
155
  // Format duration with color (warn if slow)
151
156
  let durationStr = ''
@@ -60,7 +60,9 @@ export function getCallerInfo(): CallerInfo {
60
60
  if (callerCache.size >= MAX_CACHE_SIZE) {
61
61
  // Remove oldest entry
62
62
  const firstKey = callerCache.keys().next().value
63
- callerCache.delete(firstKey)
63
+ if (firstKey !== undefined) {
64
+ callerCache.delete(firstKey)
65
+ }
64
66
  }
65
67
 
66
68
  callerCache.set(cacheKey, callerInfo)
@@ -1,82 +1,82 @@
1
- /**
2
- * FluxStack Logger - Startup Banner
3
- * Clean and beautiful startup display
4
- *
5
- * Developers can customize the banner by:
6
- * 1. Setting showBanner: false in server config
7
- * 2. Using displayStartupBanner() in app.listen() callback
8
- * 3. Creating completely custom banners with chalk
9
- */
10
-
11
- import chalk from 'chalk'
12
- import { LOG } from './index'
13
- import { FLUXSTACK_VERSION } from '../version'
14
-
15
- export interface StartupInfo {
16
- port: number
17
- host?: string
18
- apiPrefix?: string
19
- environment: string
20
- pluginCount?: number
21
- vitePort?: number
22
- viteEmbedded?: boolean // true when Vite runs programmatically with backend
23
- swaggerPath?: string
24
- liveComponents?: string[]
25
- }
26
-
27
- /**
28
- * Display clean startup banner
29
- */
30
- export function displayStartupBanner(info: StartupInfo): void {
31
- const {
32
- port,
33
- host = 'localhost',
34
- apiPrefix = '/api',
35
- environment,
36
- pluginCount = 0,
37
- vitePort,
38
- viteEmbedded = false,
39
- liveComponents = [],
40
- } = info
41
-
42
- // Build server URL
43
- const displayHost = host === '0.0.0.0' ? 'localhost' : host
44
- const serverUrl = `http://${displayHost}:${port}`
45
-
46
- // Simple ready message with URL
47
- console.log(chalk.green('\nServer ready!') + chalk.gray(` Environment: ${environment}${viteEmbedded ? ' | Vite: embedded' : ''}`))
48
- console.log(chalk.cyan(` → ${serverUrl}`))
49
-
50
- // Display Live Components
51
- if (liveComponents.length > 0) {
52
- console.log(chalk.gray(` Live Components (${liveComponents.length}): `) + chalk.yellow(liveComponents.join(', ')))
53
- }
54
-
55
- // Display plugins in compact format
56
- const plugins = (global as any).__fluxstackPlugins || []
57
- if (plugins.length > 0) {
58
- const pluginList = plugins.map((p: any) => p.name).join(', ')
59
- console.log(chalk.gray(` Plugins (${plugins.length}): `) + chalk.magenta(pluginList))
60
- }
61
-
62
- console.log('') // Empty line at the end
63
- }
64
-
65
- /**
66
- * Display simple plugin loaded message
67
- */
68
- export function logPluginLoaded(name: string, version?: string): void {
69
- const versionStr = version ? chalk.gray(`v${version}`) : ''
70
- LOG(`${chalk.green('✓')} Plugin loaded: ${chalk.cyan(name)} ${versionStr}`)
71
- }
72
-
73
- /**
74
- * Display plugin count summary
75
- */
76
- export function logPluginsSummary(count: number): void {
77
- if (count === 0) {
78
- LOG(chalk.yellow('⚠ No plugins loaded'))
79
- } else {
80
- LOG(chalk.green(`✓ ${count} plugin${count > 1 ? 's' : ''} loaded successfully`))
81
- }
82
- }
1
+ /**
2
+ * FluxStack Logger - Startup Banner
3
+ * Clean and beautiful startup display
4
+ *
5
+ * Developers can customize the banner by:
6
+ * 1. Setting showBanner: false in server config
7
+ * 2. Using displayStartupBanner() in app.listen() callback
8
+ * 3. Creating completely custom banners with chalk
9
+ */
10
+
11
+ import chalk from 'chalk'
12
+ import { LOG } from './index'
13
+ import { FLUXSTACK_VERSION } from '../version'
14
+
15
+ export interface StartupInfo {
16
+ port: number
17
+ host?: string
18
+ apiPrefix?: string
19
+ environment: string
20
+ pluginCount?: number
21
+ vitePort?: number
22
+ viteEmbedded?: boolean // true when Vite runs programmatically with backend
23
+ swaggerPath?: string
24
+ liveComponents?: string[]
25
+ }
26
+
27
+ /**
28
+ * Display clean startup banner
29
+ */
30
+ export function displayStartupBanner(info: StartupInfo): void {
31
+ const {
32
+ port,
33
+ host = 'localhost',
34
+ apiPrefix = '/api',
35
+ environment,
36
+ pluginCount = 0,
37
+ vitePort,
38
+ viteEmbedded = false,
39
+ liveComponents = [],
40
+ } = info
41
+
42
+ // Build server URL
43
+ const displayHost = host === '0.0.0.0' ? 'localhost' : host
44
+ const serverUrl = `http://${displayHost}:${port}`
45
+
46
+ // Simple ready message with URL
47
+ console.log(chalk.green('\nServer ready!') + chalk.gray(` Environment: ${environment}${viteEmbedded ? ' | Vite: embedded' : ''}`))
48
+ console.log(chalk.cyan(` → ${serverUrl}`))
49
+
50
+ // Display Live Components
51
+ if (liveComponents.length > 0) {
52
+ console.log(chalk.gray(` Live Components (${liveComponents.length}): `) + chalk.yellow(liveComponents.join(', ')))
53
+ }
54
+
55
+ // Display plugins in compact format
56
+ const plugins = (global as any).__fluxstackPlugins || []
57
+ if (plugins.length > 0) {
58
+ const pluginList = plugins.map((p: any) => p.name).join(', ')
59
+ console.log(chalk.gray(` Plugins (${plugins.length}): `) + chalk.magenta(pluginList))
60
+ }
61
+
62
+ console.log('') // Empty line at the end
63
+ }
64
+
65
+ /**
66
+ * Display simple plugin loaded message
67
+ */
68
+ export function logPluginLoaded(name: string, version?: string): void {
69
+ const versionStr = version ? chalk.gray(`v${version}`) : ''
70
+ LOG(`${chalk.green('✓')} Plugin loaded: ${chalk.cyan(name)} ${versionStr}`)
71
+ }
72
+
73
+ /**
74
+ * Display plugin count summary
75
+ */
76
+ export function logPluginsSummary(count: number): void {
77
+ if (count === 0) {
78
+ LOG(chalk.yellow('⚠ No plugins loaded'))
79
+ } else {
80
+ LOG(chalk.green(`✓ ${count} plugin${count > 1 ? 's' : ''} loaded successfully`))
81
+ }
82
+ }
@@ -1,152 +1,152 @@
1
- /**
2
- * FluxStack Logger - Winston Logger Factory
3
- * Creates Winston logger instances for each module
4
- */
5
-
6
- import winston from 'winston'
7
- import DailyRotateFile from 'winston-daily-rotate-file'
8
- import { join, dirname } from 'path'
9
- import { existsSync, mkdirSync } from 'fs'
10
- import chalk from 'chalk'
11
- import { LOGGER_CONFIG } from './config'
12
- import { LOG_SYMBOLS, LEVEL_COLORS } from './colors'
13
-
14
- // Cache for module loggers
15
- const moduleLoggers = new Map<string, winston.Logger>()
16
-
17
- /**
18
- * Console format with colors and symbols
19
- */
20
- function createConsoleFormat() {
21
- return winston.format.printf(({ timestamp, level, message }) => {
22
- const levelSymbol = LOG_SYMBOLS[level as keyof typeof LOG_SYMBOLS] || LOG_SYMBOLS.default
23
- const levelColor = LEVEL_COLORS[level as keyof typeof LEVEL_COLORS] || LEVEL_COLORS.default
24
- const timestampFormatted = chalk.gray(`[${timestamp}]`)
25
-
26
- return `${levelSymbol} ${timestampFormatted} ${levelColor(level.toUpperCase().padEnd(5))} ${message}`
27
- })
28
- }
29
-
30
- /**
31
- * File format without colors
32
- */
33
- function createFileFormat() {
34
- return winston.format.printf(({ timestamp, level, message }) => {
35
- // Remove ANSI color codes
36
- const cleanMessage = String(message).replace(/\u001b\[.*?m/g, '')
37
- return `[${timestamp}] [${level.toUpperCase()}]: ${cleanMessage}`
38
- })
39
- }
40
-
41
- /**
42
- * Create a logger for a specific module
43
- */
44
- export function getLoggerForModule(modulePath: string): winston.Logger {
45
- // Normalize path for cache key
46
- const normalizedPath = modulePath.replace(/[:/\\]/g, '_').replace(/^_/, '')
47
-
48
- // Check cache
49
- if (moduleLoggers.has(normalizedPath)) {
50
- return moduleLoggers.get(normalizedPath)!
51
- }
52
-
53
- // Create logger
54
- const logger = createLogger(normalizedPath)
55
- moduleLoggers.set(normalizedPath, logger)
56
-
57
- return logger
58
- }
59
-
60
- /**
61
- * Create a Winston logger with appropriate transports
62
- */
63
- function createLogger(modulePath: string): winston.Logger {
64
- const transports: winston.transport[] = [
65
- // Console transport (always enabled)
66
- new winston.transports.Console({
67
- format: winston.format.combine(
68
- winston.format.timestamp({ format: LOGGER_CONFIG.dateFormat }),
69
- createConsoleFormat()
70
- )
71
- })
72
- ]
73
-
74
- // Add file transports if enabled
75
- if (LOGGER_CONFIG.logToFile) {
76
- const logsDir = join(process.cwd(), 'logs', modulePath)
77
-
78
- // Ensure logs directory exists
79
- if (!existsSync(logsDir)) {
80
- mkdirSync(logsDir, { recursive: true })
81
- }
82
-
83
- const commonFileFormat = winston.format.combine(
84
- winston.format.timestamp({ format: LOGGER_CONFIG.dateFormat }),
85
- createFileFormat()
86
- )
87
-
88
- // All logs
89
- transports.push(
90
- new DailyRotateFile({
91
- filename: join(logsDir, '%DATE%-all.log'),
92
- datePattern: 'YYYY-MM-DD',
93
- maxSize: LOGGER_CONFIG.maxSize,
94
- maxFiles: LOGGER_CONFIG.maxFiles,
95
- level: LOGGER_CONFIG.level,
96
- format: commonFileFormat
97
- })
98
- )
99
-
100
- // Error logs
101
- transports.push(
102
- new DailyRotateFile({
103
- filename: join(logsDir, '%DATE%-errors.log'),
104
- datePattern: 'YYYY-MM-DD',
105
- maxSize: LOGGER_CONFIG.maxSize,
106
- maxFiles: LOGGER_CONFIG.maxFiles,
107
- level: 'error',
108
- format: commonFileFormat
109
- })
110
- )
111
-
112
- // Warning logs
113
- transports.push(
114
- new DailyRotateFile({
115
- filename: join(logsDir, '%DATE%-warnings.log'),
116
- datePattern: 'YYYY-MM-DD',
117
- maxSize: LOGGER_CONFIG.maxSize,
118
- maxFiles: LOGGER_CONFIG.maxFiles,
119
- level: 'warn',
120
- format: commonFileFormat
121
- })
122
- )
123
-
124
- // Info logs
125
- transports.push(
126
- new DailyRotateFile({
127
- filename: join(logsDir, '%DATE%-info.log'),
128
- datePattern: 'YYYY-MM-DD',
129
- maxSize: LOGGER_CONFIG.maxSize,
130
- maxFiles: LOGGER_CONFIG.maxFiles,
131
- level: 'info',
132
- format: commonFileFormat
133
- })
134
- )
135
- }
136
-
137
- return winston.createLogger({
138
- level: LOGGER_CONFIG.level,
139
- transports
140
- })
141
- }
142
-
143
- /**
144
- * Clear logger cache (useful for testing)
145
- */
146
- export function clearLoggerCache(): void {
147
- // Close all loggers before clearing
148
- for (const logger of moduleLoggers.values()) {
149
- logger.close()
150
- }
151
- moduleLoggers.clear()
152
- }
1
+ /**
2
+ * FluxStack Logger - Winston Logger Factory
3
+ * Creates Winston logger instances for each module
4
+ */
5
+
6
+ import winston from 'winston'
7
+ import DailyRotateFile from 'winston-daily-rotate-file'
8
+ import { join, dirname } from 'path'
9
+ import { existsSync, mkdirSync } from 'fs'
10
+ import chalk from 'chalk'
11
+ import { LOGGER_CONFIG } from './config'
12
+ import { LOG_SYMBOLS, LEVEL_COLORS } from './colors'
13
+
14
+ // Cache for module loggers
15
+ const moduleLoggers = new Map<string, winston.Logger>()
16
+
17
+ /**
18
+ * Console format with colors and symbols
19
+ */
20
+ function createConsoleFormat() {
21
+ return winston.format.printf(({ timestamp, level, message }) => {
22
+ const levelSymbol = LOG_SYMBOLS[level as keyof typeof LOG_SYMBOLS] || LOG_SYMBOLS.default
23
+ const levelColor = LEVEL_COLORS[level as keyof typeof LEVEL_COLORS] || LEVEL_COLORS.default
24
+ const timestampFormatted = chalk.gray(`[${timestamp}]`)
25
+
26
+ return `${levelSymbol} ${timestampFormatted} ${levelColor(level.toUpperCase().padEnd(5))} ${message}`
27
+ })
28
+ }
29
+
30
+ /**
31
+ * File format without colors
32
+ */
33
+ function createFileFormat() {
34
+ return winston.format.printf(({ timestamp, level, message }) => {
35
+ // Remove ANSI color codes
36
+ const cleanMessage = String(message).replace(/\u001b\[.*?m/g, '')
37
+ return `[${timestamp}] [${level.toUpperCase()}]: ${cleanMessage}`
38
+ })
39
+ }
40
+
41
+ /**
42
+ * Create a logger for a specific module
43
+ */
44
+ export function getLoggerForModule(modulePath: string): winston.Logger {
45
+ // Normalize path for cache key
46
+ const normalizedPath = modulePath.replace(/[:/\\]/g, '_').replace(/^_/, '')
47
+
48
+ // Check cache
49
+ if (moduleLoggers.has(normalizedPath)) {
50
+ return moduleLoggers.get(normalizedPath)!
51
+ }
52
+
53
+ // Create logger
54
+ const logger = createLogger(normalizedPath)
55
+ moduleLoggers.set(normalizedPath, logger)
56
+
57
+ return logger
58
+ }
59
+
60
+ /**
61
+ * Create a Winston logger with appropriate transports
62
+ */
63
+ function createLogger(modulePath: string): winston.Logger {
64
+ const transports: winston.transport[] = [
65
+ // Console transport (always enabled)
66
+ new winston.transports.Console({
67
+ format: winston.format.combine(
68
+ winston.format.timestamp({ format: LOGGER_CONFIG.dateFormat }),
69
+ createConsoleFormat()
70
+ )
71
+ })
72
+ ]
73
+
74
+ // Add file transports if enabled
75
+ if (LOGGER_CONFIG.logToFile) {
76
+ const logsDir = join(process.cwd(), 'logs', modulePath)
77
+
78
+ // Ensure logs directory exists
79
+ if (!existsSync(logsDir)) {
80
+ mkdirSync(logsDir, { recursive: true })
81
+ }
82
+
83
+ const commonFileFormat = winston.format.combine(
84
+ winston.format.timestamp({ format: LOGGER_CONFIG.dateFormat }),
85
+ createFileFormat()
86
+ )
87
+
88
+ // All logs
89
+ transports.push(
90
+ new DailyRotateFile({
91
+ filename: join(logsDir, '%DATE%-all.log'),
92
+ datePattern: 'YYYY-MM-DD',
93
+ maxSize: LOGGER_CONFIG.maxSize,
94
+ maxFiles: LOGGER_CONFIG.maxFiles,
95
+ level: LOGGER_CONFIG.level,
96
+ format: commonFileFormat
97
+ })
98
+ )
99
+
100
+ // Error logs
101
+ transports.push(
102
+ new DailyRotateFile({
103
+ filename: join(logsDir, '%DATE%-errors.log'),
104
+ datePattern: 'YYYY-MM-DD',
105
+ maxSize: LOGGER_CONFIG.maxSize,
106
+ maxFiles: LOGGER_CONFIG.maxFiles,
107
+ level: 'error',
108
+ format: commonFileFormat
109
+ })
110
+ )
111
+
112
+ // Warning logs
113
+ transports.push(
114
+ new DailyRotateFile({
115
+ filename: join(logsDir, '%DATE%-warnings.log'),
116
+ datePattern: 'YYYY-MM-DD',
117
+ maxSize: LOGGER_CONFIG.maxSize,
118
+ maxFiles: LOGGER_CONFIG.maxFiles,
119
+ level: 'warn',
120
+ format: commonFileFormat
121
+ })
122
+ )
123
+
124
+ // Info logs
125
+ transports.push(
126
+ new DailyRotateFile({
127
+ filename: join(logsDir, '%DATE%-info.log'),
128
+ datePattern: 'YYYY-MM-DD',
129
+ maxSize: LOGGER_CONFIG.maxSize,
130
+ maxFiles: LOGGER_CONFIG.maxFiles,
131
+ level: 'info',
132
+ format: commonFileFormat
133
+ })
134
+ )
135
+ }
136
+
137
+ return winston.createLogger({
138
+ level: LOGGER_CONFIG.level,
139
+ transports
140
+ })
141
+ }
142
+
143
+ /**
144
+ * Clear logger cache (useful for testing)
145
+ */
146
+ export function clearLoggerCache(): void {
147
+ // Close all loggers before clearing
148
+ for (const logger of moduleLoggers.values()) {
149
+ logger.close()
150
+ }
151
+ moduleLoggers.clear()
152
+ }