create-fluxstack 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/app/client/src/App.tsx +8 -0
  3. package/app/client/src/live/AuthDemo.tsx +4 -4
  4. package/core/build/bundler.ts +40 -26
  5. package/core/build/flux-plugins-generator.ts +325 -325
  6. package/core/build/index.ts +92 -21
  7. package/core/cli/command-registry.ts +44 -46
  8. package/core/cli/commands/build.ts +11 -6
  9. package/core/cli/commands/create.ts +7 -5
  10. package/core/cli/commands/dev.ts +6 -5
  11. package/core/cli/commands/help.ts +3 -2
  12. package/core/cli/commands/make-plugin.ts +8 -7
  13. package/core/cli/commands/plugin-add.ts +60 -43
  14. package/core/cli/commands/plugin-deps.ts +73 -57
  15. package/core/cli/commands/plugin-list.ts +44 -41
  16. package/core/cli/commands/plugin-remove.ts +33 -22
  17. package/core/cli/generators/component.ts +770 -769
  18. package/core/cli/generators/controller.ts +9 -8
  19. package/core/cli/generators/index.ts +148 -146
  20. package/core/cli/generators/interactive.ts +228 -227
  21. package/core/cli/generators/plugin.ts +11 -10
  22. package/core/cli/generators/prompts.ts +83 -82
  23. package/core/cli/generators/route.ts +7 -6
  24. package/core/cli/generators/service.ts +10 -9
  25. package/core/cli/generators/template-engine.ts +2 -1
  26. package/core/cli/generators/types.ts +7 -7
  27. package/core/cli/generators/utils.ts +191 -191
  28. package/core/cli/index.ts +9 -8
  29. package/core/cli/plugin-discovery.ts +2 -2
  30. package/core/client/hooks/useAuth.ts +48 -48
  31. package/core/client/standalone.ts +18 -17
  32. package/core/client/state/createStore.ts +192 -192
  33. package/core/client/state/index.ts +14 -14
  34. package/core/config/index.ts +1 -0
  35. package/core/framework/client.ts +131 -131
  36. package/core/framework/index.ts +7 -7
  37. package/core/framework/server.ts +72 -112
  38. package/core/framework/types.ts +2 -2
  39. package/core/plugins/built-in/live-components/commands/create-live-component.ts +6 -3
  40. package/core/plugins/built-in/monitoring/index.ts +110 -68
  41. package/core/plugins/built-in/static/index.ts +2 -2
  42. package/core/plugins/built-in/swagger/index.ts +9 -9
  43. package/core/plugins/built-in/vite/index.ts +3 -3
  44. package/core/plugins/built-in/vite/vite-dev.ts +3 -3
  45. package/core/plugins/config.ts +50 -47
  46. package/core/plugins/discovery.ts +10 -4
  47. package/core/plugins/executor.ts +2 -2
  48. package/core/plugins/index.ts +206 -203
  49. package/core/plugins/manager.ts +21 -20
  50. package/core/plugins/registry.ts +76 -12
  51. package/core/plugins/types.ts +14 -14
  52. package/core/server/framework.ts +3 -189
  53. package/core/server/live/auto-generated-components.ts +11 -29
  54. package/core/server/live/index.ts +41 -31
  55. package/core/server/live/websocket-plugin.ts +11 -1
  56. package/core/server/middleware/elysia-helpers.ts +16 -15
  57. package/core/server/middleware/errorHandling.ts +14 -14
  58. package/core/server/middleware/index.ts +31 -31
  59. package/core/server/plugins/database.ts +181 -180
  60. package/core/server/plugins/static-files-plugin.ts +4 -3
  61. package/core/server/plugins/swagger.ts +11 -8
  62. package/core/server/rooms/RoomBroadcaster.ts +11 -10
  63. package/core/server/rooms/RoomSystem.ts +14 -11
  64. package/core/server/services/BaseService.ts +7 -7
  65. package/core/server/services/ServiceContainer.ts +5 -5
  66. package/core/server/services/index.ts +8 -8
  67. package/core/templates/create-project.ts +28 -27
  68. package/core/testing/index.ts +9 -9
  69. package/core/testing/setup.ts +73 -73
  70. package/core/types/api.ts +168 -168
  71. package/core/types/config.ts +5 -5
  72. package/core/types/index.ts +1 -1
  73. package/core/types/plugin.ts +2 -2
  74. package/core/types/types.ts +3 -3
  75. package/core/utils/build-logger.ts +324 -324
  76. package/core/utils/config-schema.ts +480 -480
  77. package/core/utils/env.ts +10 -8
  78. package/core/utils/errors/codes.ts +114 -114
  79. package/core/utils/errors/handlers.ts +30 -20
  80. package/core/utils/errors/index.ts +54 -46
  81. package/core/utils/errors/middleware.ts +113 -113
  82. package/core/utils/helpers.ts +19 -16
  83. package/core/utils/logger/colors.ts +114 -114
  84. package/core/utils/logger/config.ts +2 -2
  85. package/core/utils/logger/formatter.ts +82 -82
  86. package/core/utils/logger/group-logger.ts +101 -101
  87. package/core/utils/logger/index.ts +13 -3
  88. package/core/utils/logger/startup-banner.ts +2 -2
  89. package/core/utils/logger/winston-logger.ts +152 -152
  90. package/core/utils/monitoring/index.ts +211 -211
  91. package/core/utils/sync-version.ts +67 -66
  92. package/core/utils/version.ts +1 -1
  93. package/package.json +104 -100
  94. package/playwright-report/index.html +85 -0
  95. package/playwright.config.ts +31 -0
  96. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  97. package/plugins/crypto-auth/client/components/index.ts +11 -11
  98. package/plugins/crypto-auth/client/index.ts +11 -11
  99. package/plugins/crypto-auth/package.json +65 -65
  100. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  101. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +6 -5
  102. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +6 -5
  103. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +3 -3
  104. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  105. package/plugins/crypto-auth/server/middlewares.ts +19 -19
  106. package/vite.config.ts +13 -0
  107. package/app/client/.live-stubs/LiveAdminPanel.js +0 -5
  108. package/app/client/.live-stubs/LiveCounter.js +0 -9
  109. package/app/client/.live-stubs/LiveForm.js +0 -11
  110. package/app/client/.live-stubs/LiveLocalCounter.js +0 -8
  111. package/app/client/.live-stubs/LivePingPong.js +0 -10
  112. package/app/client/.live-stubs/LiveRoomChat.js +0 -11
  113. package/app/client/.live-stubs/LiveSharedCounter.js +0 -10
  114. package/app/client/.live-stubs/LiveUpload.js +0 -15
  115. package/app/server/live/register-components.ts +0 -19
  116. package/core/build/live-components-generator.ts +0 -321
  117. package/core/live/ComponentRegistry.ts +0 -403
  118. package/core/live/types.ts +0 -241
  119. package/workspace.json +0 -6
@@ -1,7 +1,7 @@
1
1
  import { copyFileSync, writeFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync } from "fs"
2
2
  import { join } from "path"
3
3
  import type { FluxStackConfig } from "../config"
4
- import type { BuildResult, BuildManifest } from "../types/build"
4
+ import type { BuildResult, BuildManifest, BundleResult, OptimizationResult } from "../types/build"
5
5
  import { Bundler } from "./bundler"
6
6
  import { Optimizer } from "./optimizer"
7
7
  import { FLUXSTACK_VERSION } from "../utils/version"
@@ -9,14 +9,69 @@ import { buildLogger } from "../utils/build-logger"
9
9
  import type { PluginRegistry } from "../plugins/registry"
10
10
  import type { BuildContext, BuildAssetContext, BuildErrorContext } from "../plugins/types"
11
11
 
12
+ /**
13
+ * Runtime shape of config properties - the FluxStackConfig type uses
14
+ * complex conditional inference via defineConfig/defineNestedConfig
15
+ * which causes spread results to collapse to {} at the type level.
16
+ * We declare the actual runtime shapes explicitly.
17
+ */
18
+ interface BuildConfigRuntime {
19
+ target: string
20
+ outDir: string
21
+ sourceMaps: boolean
22
+ clean: boolean
23
+ mode: string
24
+ external: string[]
25
+ optimize: boolean
26
+ optimization: {
27
+ minify: boolean
28
+ treeshake: boolean
29
+ compress: boolean
30
+ splitChunks: boolean
31
+ bundleAnalyzer: boolean
32
+ removeUnusedCSS: boolean
33
+ optimizeImages: boolean
34
+ }
35
+ }
36
+
37
+ interface OptimizationConfigRuntime {
38
+ minify: boolean
39
+ treeshake: boolean
40
+ compress: boolean
41
+ splitChunks: boolean
42
+ bundleAnalyzer: boolean
43
+ removeUnusedCSS: boolean
44
+ optimizeImages: boolean
45
+ }
46
+
47
+ interface AppConfigRuntime {
48
+ name: string
49
+ version: string
50
+ env: string
51
+ debug: boolean
52
+ }
53
+
54
+ interface ClientBuildRuntime {
55
+ outDir: string
56
+ sourceMaps: boolean
57
+ }
58
+
59
+ /** Augmented config type that resolves the spread-collapsed properties */
60
+ type ResolvedFluxStackConfig = FluxStackConfig & {
61
+ build: BuildConfigRuntime
62
+ optimization: OptimizationConfigRuntime
63
+ app: AppConfigRuntime
64
+ clientBuild: ClientBuildRuntime
65
+ }
66
+
12
67
  export class FluxStackBuilder {
13
- private config: FluxStackConfig
68
+ private config: ResolvedFluxStackConfig
14
69
  private bundler: Bundler
15
70
  private optimizer: Optimizer
16
71
  private pluginRegistry?: PluginRegistry
17
72
 
18
73
  constructor(config: FluxStackConfig, pluginRegistry?: PluginRegistry) {
19
- this.config = config
74
+ this.config = config as ResolvedFluxStackConfig
20
75
  this.pluginRegistry = pluginRegistry
21
76
 
22
77
  const optimization = this.config.optimization || {
@@ -28,22 +83,24 @@ export class FluxStackBuilder {
28
83
  bundleAnalyzer: false
29
84
  }
30
85
 
86
+ const buildCfg = this.config.build
87
+
31
88
  // Initialize bundler with configuration
32
89
  this.bundler = new Bundler({
33
- target: config.build.target ?? 'bun',
34
- outDir: config.build.outDir ?? 'dist',
35
- sourceMaps: config.build.sourceMaps ?? false,
36
- minify: optimization.minify,
37
- external: config.build.external || []
90
+ target: (buildCfg.target ?? 'bun') as 'bun' | 'node' | 'docker',
91
+ outDir: buildCfg.outDir ?? 'dist',
92
+ sourceMaps: buildCfg.sourceMaps ?? false,
93
+ minify: optimization.minify as boolean ?? true,
94
+ external: buildCfg.external || []
38
95
  })
39
96
 
40
97
  // Initialize optimizer with configuration
41
98
  this.optimizer = new Optimizer({
42
- treeshake: optimization.treeshake ?? true,
43
- compress: optimization.compress || false,
44
- removeUnusedCSS: optimization.removeUnusedCSS || false,
45
- optimizeImages: optimization.optimizeImages || false,
46
- bundleAnalysis: optimization.bundleAnalyzer || false
99
+ treeshake: Boolean(optimization.treeshake ?? true),
100
+ compress: Boolean(optimization.compress || false),
101
+ removeUnusedCSS: Boolean(optimization.removeUnusedCSS || false),
102
+ optimizeImages: Boolean(optimization.optimizeImages || false),
103
+ bundleAnalysis: Boolean(optimization.bundleAnalyzer || false)
47
104
  })
48
105
  }
49
106
 
@@ -429,19 +486,33 @@ MONITORING_ENABLED=true
429
486
  }
430
487
 
431
488
  private async generateManifest(
432
- clientResult: any,
433
- serverResult: any,
434
- optimizationResult?: any
489
+ clientResult: BundleResult,
490
+ serverResult: BundleResult,
491
+ optimizationResult?: OptimizationResult
435
492
  ): Promise<BuildManifest> {
493
+ const target = (this.config.build.target ?? 'bun') as import("../types/build").BuildTarget
494
+ const mode = (this.config.build.mode ?? 'production') as import("../types/build").BuildMode
495
+
496
+ // Map string asset paths to AssetManifest objects
497
+ const clientAssets: import("../types/build").AssetManifest[] = (clientResult.assets || []).map(
498
+ (assetPath) => ({
499
+ name: assetPath.split('/').pop() || assetPath,
500
+ file: assetPath,
501
+ size: 0,
502
+ hash: '',
503
+ type: 'asset'
504
+ })
505
+ )
506
+
436
507
  return {
437
508
  version: this.config.app.version ?? '0.0.0',
438
509
  timestamp: new Date().toISOString(),
439
- target: this.config.build.target ?? 'bun',
440
- mode: this.config.build.mode ?? 'production',
510
+ target,
511
+ mode,
441
512
  client: {
442
513
  entryPoints: [],
443
514
  chunks: [],
444
- assets: clientResult.assets || [],
515
+ assets: clientAssets,
445
516
  publicPath: '/'
446
517
  },
447
518
  server: {
@@ -473,7 +544,7 @@ MONITORING_ENABLED=true
473
544
  /**
474
545
  * Execute plugin hooks for build process
475
546
  */
476
- private async executePluginHooks(hookName: string, context: any): Promise<void> {
547
+ private async executePluginHooks(hookName: string, context: unknown): Promise<void> {
477
548
  if (!this.pluginRegistry) return
478
549
 
479
550
  const loadOrder = this.pluginRegistry.getLoadOrder()
@@ -482,7 +553,7 @@ MONITORING_ENABLED=true
482
553
  const plugin = this.pluginRegistry.get(pluginName)
483
554
  if (!plugin) continue
484
555
 
485
- const hookFn = (plugin as any)[hookName]
556
+ const hookFn = (plugin as unknown as Record<string, unknown>)[hookName]
486
557
  if (typeof hookFn === 'function') {
487
558
  try {
488
559
  await hookFn(context)
@@ -1,7 +1,10 @@
1
- import type { CliCommand, CliContext, CliArgument, CliOption } from "../plugins/types"
1
+ import type { CliCommand, CliContext, CliArgument, CliOption, PluginConfigSchema } from "../plugins/types"
2
2
  import { fluxStackConfig } from "@config"
3
3
  import { logger } from "@core/utils/logger"
4
+ import { buildLogger } from "@core/utils/build-logger"
4
5
  import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
6
+ import { createHash } from "crypto"
7
+ import { createPluginUtils } from "../plugins/config"
5
8
 
6
9
  export class CliCommandRegistry {
7
10
  private commands = new Map<string, CliCommand>()
@@ -13,7 +16,7 @@ export class CliCommandRegistry {
13
16
 
14
17
  this.context = {
15
18
  config,
16
- logger: logger as any,
19
+ logger,
17
20
  utils: {
18
21
  createTimer,
19
22
  formatBytes,
@@ -21,8 +24,7 @@ export class CliCommandRegistry {
21
24
  isDevelopment,
22
25
  getEnvironment: () => process.env.NODE_ENV || 'development',
23
26
  createHash: (data: string) => {
24
- const crypto = require('crypto')
25
- return crypto.createHash('sha256').update(data).digest('hex')
27
+ return createHash('sha256').update(data).digest('hex')
26
28
  },
27
29
  deepMerge: (target: Record<string, unknown>, source: Record<string, unknown>) => {
28
30
  const result = { ...target }
@@ -35,12 +37,8 @@ export class CliCommandRegistry {
35
37
  }
36
38
  return result
37
39
  },
38
- validateSchema: (_data: unknown, _schema: unknown) => {
39
- try {
40
- return { valid: true, errors: [] }
41
- } catch (error) {
42
- return { valid: false, errors: [error instanceof Error ? error.message : 'Validation failed'] }
43
- }
40
+ validateSchema: (data: Record<string, unknown>, schema: PluginConfigSchema) => {
41
+ return createPluginUtils(logger).validateSchema(data, schema)
44
42
  }
45
43
  },
46
44
  workingDir: process.cwd(),
@@ -103,9 +101,9 @@ export class CliCommandRegistry {
103
101
 
104
102
  async execute(commandName: string, args: string[]): Promise<number> {
105
103
  const command = this.get(commandName)
106
-
104
+
107
105
  if (!command) {
108
- console.error(`❌ Unknown command: ${commandName}`)
106
+ buildLogger.error(`❌ Unknown command: ${commandName}`)
109
107
  this.showHelp()
110
108
  return 1
111
109
  }
@@ -113,24 +111,24 @@ export class CliCommandRegistry {
113
111
  try {
114
112
  // Parse arguments and options
115
113
  const { parsedArgs, parsedOptions } = this.parseArgs(command, args)
116
-
114
+
117
115
  // Validate required arguments
118
116
  if (command.arguments) {
119
117
  for (let i = 0; i < command.arguments.length; i++) {
120
118
  const arg = command.arguments[i]
121
119
  if (arg.required && !parsedArgs[i]) {
122
- console.error(`❌ Missing required argument: ${arg.name}`)
120
+ buildLogger.error(`❌ Missing required argument: ${arg.name}`)
123
121
  this.showCommandHelp(command)
124
122
  return 1
125
123
  }
126
124
  }
127
125
  }
128
-
126
+
129
127
  // Validate required options
130
128
  if (command.options) {
131
129
  for (const option of command.options) {
132
130
  if (option.required && !(option.name in parsedOptions)) {
133
- console.error(`❌ Missing required option: --${option.name}`)
131
+ buildLogger.error(`❌ Missing required option: --${option.name}`)
134
132
  this.showCommandHelp(command)
135
133
  return 1
136
134
  }
@@ -140,16 +138,16 @@ export class CliCommandRegistry {
140
138
  // Execute command
141
139
  await command.handler(parsedArgs, parsedOptions, this.context)
142
140
  return 0
143
-
141
+
144
142
  } catch (error) {
145
- console.error(`❌ Command failed:`, error instanceof Error ? error.message : String(error))
143
+ buildLogger.error('❌ Command failed:', error instanceof Error ? error.message : String(error))
146
144
  return 1
147
145
  }
148
146
  }
149
147
 
150
- private parseArgs(command: CliCommand, args: string[]): { parsedArgs: any[], parsedOptions: any } {
151
- const parsedArgs: any[] = []
152
- const parsedOptions: any = {}
148
+ private parseArgs(command: CliCommand, args: string[]): { parsedArgs: unknown[], parsedOptions: Record<string, unknown> } {
149
+ const parsedArgs: unknown[] = []
150
+ const parsedOptions: Record<string, unknown> = {}
153
151
 
154
152
  let i = 0
155
153
  while (i < args.length) {
@@ -166,7 +164,7 @@ export class CliCommandRegistry {
166
164
  } else if (option.type === 'array') {
167
165
  parsedOptions[optionName] = parsedOptions[optionName] || []
168
166
  if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
169
- parsedOptions[optionName].push(args[++i])
167
+ (parsedOptions[optionName] as unknown[]).push(args[++i])
170
168
  }
171
169
  } else {
172
170
  if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
@@ -225,7 +223,7 @@ export class CliCommandRegistry {
225
223
  return { parsedArgs, parsedOptions }
226
224
  }
227
225
 
228
- private convertType(value: string, type?: 'string' | 'number' | 'boolean' | 'array'): any {
226
+ private convertType(value: string, type?: 'string' | 'number' | 'boolean' | 'array'): string | number | boolean | string[] {
229
227
  if (!type || type === 'string') return value
230
228
  if (type === 'number') return Number(value)
231
229
  if (type === 'boolean') return value.toLowerCase() === 'true'
@@ -234,7 +232,7 @@ export class CliCommandRegistry {
234
232
  }
235
233
 
236
234
  showHelp(): void {
237
- console.log(`
235
+ buildLogger.info(`
238
236
  ⚡ FluxStack Framework CLI
239
237
 
240
238
  Usage:
@@ -244,16 +242,16 @@ Usage:
244
242
  Built-in Commands:`)
245
243
 
246
244
  const categories = this.getAllByCategory()
247
-
245
+
248
246
  for (const [category, commands] of categories) {
249
- console.log(`\n${category}:`)
247
+ buildLogger.info(`\n${category}:`)
250
248
  for (const command of commands) {
251
249
  const aliases = command.aliases?.length ? ` (${command.aliases.join(', ')})` : ''
252
- console.log(` ${command.name}${aliases.padEnd(20)} ${command.description}`)
250
+ buildLogger.info(` ${command.name}${aliases.padEnd(20)} ${command.description}`)
253
251
  }
254
252
  }
255
253
 
256
- console.log(`
254
+ buildLogger.info(`
257
255
  Examples:
258
256
  flux dev # Start development server
259
257
  flux build --production # Build for production
@@ -264,13 +262,13 @@ Use "flux help <command>" for more information about a specific command.`)
264
262
  }
265
263
 
266
264
  showCommandHelp(command: CliCommand): void {
267
- console.log(`\n${command.description}`)
268
-
265
+ buildLogger.info(`\n${command.description}`)
266
+
269
267
  if (command.usage) {
270
- console.log(`\nUsage:\n ${command.usage}`)
268
+ buildLogger.info(`\nUsage:\n ${command.usage}`)
271
269
  } else {
272
270
  let usage = `flux ${command.name}`
273
-
271
+
274
272
  if (command.arguments) {
275
273
  for (const arg of command.arguments) {
276
274
  if (arg.required) {
@@ -280,42 +278,42 @@ Use "flux help <command>" for more information about a specific command.`)
280
278
  }
281
279
  }
282
280
  }
283
-
281
+
284
282
  if (command.options?.length) {
285
283
  usage += ` [options]`
286
284
  }
287
-
288
- console.log(`\nUsage:\n ${usage}`)
285
+
286
+ buildLogger.info(`\nUsage:\n ${usage}`)
289
287
  }
290
-
288
+
291
289
  if (command.arguments?.length) {
292
- console.log(`\nArguments:`)
290
+ buildLogger.info(`\nArguments:`)
293
291
  for (const arg of command.arguments) {
294
292
  const required = arg.required ? ' (required)' : ''
295
293
  const defaultValue = arg.default !== undefined ? ` (default: ${arg.default})` : ''
296
- console.log(` ${arg.name.padEnd(15)} ${arg.description}${required}${defaultValue}`)
294
+ buildLogger.info(` ${arg.name.padEnd(15)} ${arg.description}${required}${defaultValue}`)
297
295
  }
298
296
  }
299
-
297
+
300
298
  if (command.options?.length) {
301
- console.log(`\nOptions:`)
299
+ buildLogger.info(`\nOptions:`)
302
300
  for (const option of command.options) {
303
301
  const short = option.short ? `-${option.short}, ` : ' '
304
302
  const required = option.required ? ' (required)' : ''
305
303
  const defaultValue = option.default !== undefined ? ` (default: ${option.default})` : ''
306
- console.log(` ${short}--${option.name.padEnd(15)} ${option.description}${required}${defaultValue}`)
304
+ buildLogger.info(` ${short}--${option.name.padEnd(15)} ${option.description}${required}${defaultValue}`)
307
305
  }
308
306
  }
309
-
307
+
310
308
  if (command.examples?.length) {
311
- console.log(`\nExamples:`)
309
+ buildLogger.info(`\nExamples:`)
312
310
  for (const example of command.examples) {
313
- console.log(` ${example}`)
311
+ buildLogger.info(` ${example}`)
314
312
  }
315
313
  }
316
-
314
+
317
315
  if (command.aliases?.length) {
318
- console.log(`\nAliases: ${command.aliases.join(', ')}`)
316
+ buildLogger.info(`\nAliases: ${command.aliases.join(', ')}`)
319
317
  }
320
318
  }
321
319
  }
@@ -48,19 +48,24 @@ export const buildCommand: CLICommand = {
48
48
  await pluginManager.initialize()
49
49
  // Sync plugins to registry (same as framework does)
50
50
  const discoveredPlugins = pluginManager.getRegistry().getAll()
51
+ const registryInternals = pluginRegistry as unknown as {
52
+ plugins: Map<string, import('@core/plugins/types').FluxStack.Plugin>
53
+ dependencies: Map<string, string[]>
54
+ loadOrder: string[]
55
+ updateLoadOrder(): void
56
+ }
51
57
  for (const plugin of discoveredPlugins) {
52
58
  if (!pluginRegistry.has(plugin.name)) {
53
- (pluginRegistry as any).plugins.set(plugin.name, plugin)
59
+ registryInternals.plugins.set(plugin.name, plugin)
54
60
  if (plugin.dependencies) {
55
- (pluginRegistry as any).dependencies.set(plugin.name, plugin.dependencies)
61
+ registryInternals.dependencies.set(plugin.name, plugin.dependencies)
56
62
  }
57
63
  }
58
64
  }
59
65
  try {
60
- (pluginRegistry as any).updateLoadOrder()
61
- } catch (error) {
62
- const plugins = (pluginRegistry as any).plugins as Map<string, any>
63
- ;(pluginRegistry as any).loadOrder = Array.from(plugins.keys())
66
+ registryInternals.updateLoadOrder()
67
+ } catch {
68
+ registryInternals.loadOrder = Array.from(registryInternals.plugins.keys())
64
69
  }
65
70
  } catch (error) {
66
71
  context.logger.warn('Failed to load plugins for build hooks', { error })
@@ -5,6 +5,7 @@
5
5
 
6
6
  import type { CLICommand } from '../command-registry'
7
7
  import { ProjectCreator } from '@core/templates/create-project'
8
+ import { buildLogger } from '@core/utils/build-logger'
8
9
 
9
10
  export const createCommand: CLICommand = {
10
11
  name: 'create',
@@ -32,22 +33,23 @@ export const createCommand: CLICommand = {
32
33
  }
33
34
  ],
34
35
  handler: async (args, options, context) => {
35
- const [projectName, template] = args
36
+ const projectName = args[0] as string
37
+ const template = args[1] as string | undefined
36
38
 
37
39
  if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
38
- console.error("❌ Project name can only contain letters, numbers, hyphens, and underscores")
40
+ buildLogger.error("❌ Project name can only contain letters, numbers, hyphens, and underscores")
39
41
  return
40
42
  }
41
43
 
42
44
  try {
43
45
  const creator = new ProjectCreator({
44
- name: projectName,
45
- template: template as 'basic' | 'full' || 'basic'
46
+ name: projectName as string,
47
+ template: (template as 'basic' | 'full') || 'basic'
46
48
  })
47
49
 
48
50
  await creator.create()
49
51
  } catch (error) {
50
- console.error("❌ Failed to create project:", error instanceof Error ? error.message : String(error))
52
+ buildLogger.error("❌ Failed to create project:", error instanceof Error ? error.message : String(error))
51
53
  throw error
52
54
  }
53
55
  }
@@ -5,6 +5,7 @@
5
5
 
6
6
  import type { CLICommand } from '../command-registry'
7
7
  import { serverConfig, clientConfig } from '@config'
8
+ import { buildLogger } from '@core/utils/build-logger'
8
9
 
9
10
  export const devCommand: CLICommand = {
10
11
  name: 'dev',
@@ -53,7 +54,7 @@ export const devCommand: CLICommand = {
53
54
  const backendOnly = options['backend-only'] === true
54
55
 
55
56
  if (frontendOnly && backendOnly) {
56
- console.error('❌ Cannot use --frontend-only and --backend-only together')
57
+ buildLogger.error('❌ Cannot use --frontend-only and --backend-only together')
57
58
  process.exit(1)
58
59
  }
59
60
 
@@ -67,21 +68,21 @@ export const devCommand: CLICommand = {
67
68
 
68
69
  const fluxstackMode = backendOnly ? 'backend-only' : 'full-stack'
69
70
 
70
- console.log(`⚡ Starting ${mode} development server...`)
71
+ buildLogger.info(`⚡ Starting ${mode} development server...`)
71
72
 
72
73
  const devProcess = spawn("bun", ["--watch", entryPoint], {
73
74
  stdio: "inherit",
74
75
  cwd: process.cwd(),
75
76
  env: {
76
77
  ...process.env,
77
- FRONTEND_PORT: options['frontend-port'].toString(),
78
- BACKEND_PORT: options.port.toString(),
78
+ FRONTEND_PORT: String(options['frontend-port']),
79
+ BACKEND_PORT: String(options.port),
79
80
  FLUXSTACK_MODE: fluxstackMode
80
81
  }
81
82
  })
82
83
 
83
84
  process.on('SIGINT', () => {
84
- console.log('\n🛑 Shutting down gracefully...')
85
+ buildLogger.info('\n🛑 Shutting down gracefully...')
85
86
  devProcess.kill('SIGTERM')
86
87
  setTimeout(() => {
87
88
  devProcess.kill('SIGKILL')
@@ -5,6 +5,7 @@
5
5
 
6
6
  import type { CLICommand } from '../command-registry'
7
7
  import { cliRegistry } from '../command-registry'
8
+ import { buildLogger } from '@core/utils/build-logger'
8
9
 
9
10
  export const helpCommand: CLICommand = {
10
11
  name: 'help',
@@ -20,11 +21,11 @@ export const helpCommand: CLICommand = {
20
21
  ],
21
22
  handler: async (args, options, context) => {
22
23
  if (args[0]) {
23
- const targetCommand = cliRegistry.get(args[0])
24
+ const targetCommand = cliRegistry.get(args[0] as string)
24
25
  if (targetCommand) {
25
26
  cliRegistry.showCommandHelp(targetCommand)
26
27
  } else {
27
- console.error(`❌ Unknown command: ${args[0]}`)
28
+ buildLogger.error(`❌ Unknown command: ${args[0]}`)
28
29
  cliRegistry.showHelp()
29
30
  }
30
31
  } else {
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { CLICommand } from '../command-registry'
7
+ import { buildLogger } from '@core/utils/build-logger'
7
8
 
8
9
  export const makePluginCommand: CLICommand = {
9
10
  name: 'make:plugin',
@@ -49,10 +50,10 @@ export const makePluginCommand: CLICommand = {
49
50
  }
50
51
  ],
51
52
  handler: async (args, options, context) => {
52
- const [name] = args
53
+ const name = args[0] as string
53
54
 
54
55
  if (!/^[a-zA-Z0-9-_]+$/.test(name)) {
55
- console.error("❌ Plugin name can only contain letters, numbers, hyphens, and underscores")
56
+ buildLogger.error("❌ Plugin name can only contain letters, numbers, hyphens, and underscores")
56
57
  return
57
58
  }
58
59
 
@@ -61,7 +62,7 @@ export const makePluginCommand: CLICommand = {
61
62
  const pluginGenerator = generatorRegistry.get('plugin')
62
63
 
63
64
  if (!pluginGenerator) {
64
- console.error("❌ Plugin generator not found")
65
+ buildLogger.error("❌ Plugin generator not found")
65
66
  return
66
67
  }
67
68
 
@@ -74,16 +75,16 @@ export const makePluginCommand: CLICommand = {
74
75
 
75
76
  const generatorOptions = {
76
77
  name,
77
- template: options.template,
78
- force: options.force,
78
+ template: options.template as string | undefined,
79
+ force: options.force as boolean | undefined,
79
80
  dryRun: false,
80
- description: options.description
81
+ description: options.description as string | undefined
81
82
  }
82
83
 
83
84
  try {
84
85
  await pluginGenerator.generate(generatorContext, generatorOptions)
85
86
  } catch (error) {
86
- console.error("❌ Failed to create plugin:", error instanceof Error ? error.message : String(error))
87
+ buildLogger.error("❌ Failed to create plugin:", error instanceof Error ? error.message : String(error))
87
88
  throw error
88
89
  }
89
90
  }