create-fluxstack 1.16.0 → 1.17.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 (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 +73 -113
  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,192 +1,192 @@
1
- import { existsSync } from "fs"
2
- import { join } from "path"
3
-
4
- export class GeneratorUtils {
5
- static validateName(name: string): { valid: boolean; error?: string } {
6
- if (!name || typeof name !== 'string') {
7
- return { valid: false, error: 'Name is required' }
8
- }
9
-
10
- const trimmed = name.trim()
11
- if (trimmed.length === 0) {
12
- return { valid: false, error: 'Name cannot be empty' }
13
- }
14
-
15
- if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmed)) {
16
- return { valid: false, error: 'Name must start with a letter and contain only letters, numbers, hyphens, and underscores' }
17
- }
18
-
19
- if (trimmed.length > 100) {
20
- return { valid: false, error: 'Name must be less than 100 characters' }
21
- }
22
-
23
- return { valid: true }
24
- }
25
-
26
- static validatePath(path: string): { valid: boolean; error?: string } {
27
- if (!path || typeof path !== 'string') {
28
- return { valid: true } // Path is optional
29
- }
30
-
31
- const trimmed = path.trim()
32
- if (trimmed.length === 0) {
33
- return { valid: true }
34
- }
35
-
36
- // Check for invalid characters
37
- if (/[<>:"|?*]/.test(trimmed)) {
38
- return { valid: false, error: 'Path contains invalid characters' }
39
- }
40
-
41
- // Check for absolute paths (should be relative)
42
- if (trimmed.startsWith('/') || /^[a-zA-Z]:/.test(trimmed)) {
43
- return { valid: false, error: 'Path should be relative to project root' }
44
- }
45
-
46
- return { valid: true }
47
- }
48
-
49
- static checkFileExists(workingDir: string, filePath: string): boolean {
50
- const fullPath = join(workingDir, filePath)
51
- return existsSync(fullPath)
52
- }
53
-
54
- static getDefaultPath(type: string, name: string): string {
55
- const kebabName = this.toKebabCase(name)
56
- const pascalName = this.toPascalCase(name)
57
-
58
- switch (type) {
59
- case 'controller':
60
- return `app/server/controllers/${kebabName}.controller.ts`
61
- case 'service':
62
- return `app/server/services/${kebabName}.service.ts`
63
- case 'route':
64
- return `app/server/routes/${kebabName}.routes.ts`
65
- case 'component':
66
- return `app/client/src/components/${pascalName}/${pascalName}.tsx`
67
- default:
68
- return `${kebabName}.ts`
69
- }
70
- }
71
-
72
- static getRelatedFiles(type: string, name: string): string[] {
73
- const kebabName = this.toKebabCase(name)
74
- const pascalName = this.toPascalCase(name)
75
-
76
- switch (type) {
77
- case 'controller':
78
- return [
79
- `app/server/services/${kebabName}.service.ts`,
80
- `app/server/schemas/${kebabName}.schema.ts`,
81
- `app/server/routes/${kebabName}.routes.ts`
82
- ]
83
- case 'service':
84
- return [
85
- `app/server/repositories/${kebabName}.repository.ts`,
86
- `app/server/controllers/${kebabName}.controller.ts`
87
- ]
88
- case 'component':
89
- return [
90
- `app/client/src/components/${pascalName}/${pascalName}.css`,
91
- `app/client/src/components/${pascalName}/index.ts`,
92
- `app/client/src/components/${pascalName}/${pascalName}.test.tsx`,
93
- `app/client/src/components/${pascalName}/${pascalName}.stories.tsx`
94
- ]
95
- case 'route':
96
- return [
97
- `app/server/controllers/${kebabName}.controller.ts`,
98
- `app/server/middleware/${kebabName}.middleware.ts`
99
- ]
100
- default:
101
- return []
102
- }
103
- }
104
-
105
- static formatFileSize(bytes: number): string {
106
- const units = ['B', 'KB', 'MB', 'GB']
107
- let size = bytes
108
- let unitIndex = 0
109
-
110
- while (size >= 1024 && unitIndex < units.length - 1) {
111
- size /= 1024
112
- unitIndex++
113
- }
114
-
115
- return `${size.toFixed(1)} ${units[unitIndex]}`
116
- }
117
-
118
- static getTemplateVariables(name: string, additionalVars: Record<string, any> = {}): Record<string, any> {
119
- return {
120
- name,
121
- Name: this.capitalize(name),
122
- NAME: name.toUpperCase(),
123
- kebabName: this.toKebabCase(name),
124
- camelName: this.toCamelCase(name),
125
- pascalName: this.toPascalCase(name),
126
- snakeName: this.toSnakeCase(name),
127
- timestamp: new Date().toISOString(),
128
- date: new Date().toLocaleDateString(),
129
- time: new Date().toLocaleTimeString(),
130
- year: new Date().getFullYear(),
131
- month: new Date().getMonth() + 1,
132
- day: new Date().getDate(),
133
- ...additionalVars
134
- }
135
- }
136
-
137
- // String transformation utilities
138
- static capitalize(str: string): string {
139
- return str.charAt(0).toUpperCase() + str.slice(1)
140
- }
141
-
142
- static toCamelCase(str: string): string {
143
- return str
144
- .replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
145
- .replace(/^[A-Z]/, char => char.toLowerCase())
146
- }
147
-
148
- static toPascalCase(str: string): string {
149
- return this.capitalize(this.toCamelCase(str))
150
- }
151
-
152
- static toKebabCase(str: string): string {
153
- return str
154
- .replace(/([a-z])([A-Z])/g, '$1-$2')
155
- .replace(/[\s_]+/g, '-')
156
- .toLowerCase()
157
- }
158
-
159
- static toSnakeCase(str: string): string {
160
- return str
161
- .replace(/([a-z])([A-Z])/g, '$1_$2')
162
- .replace(/[\s-]+/g, '_')
163
- .toLowerCase()
164
- }
165
-
166
- static pluralize(str: string): string {
167
- // Simple pluralization - in a real implementation you'd use a proper library
168
- if (str.endsWith('y')) {
169
- return str.slice(0, -1) + 'ies'
170
- }
171
- if (str.endsWith('s') || str.endsWith('sh') || str.endsWith('ch') || str.endsWith('x') || str.endsWith('z')) {
172
- return str + 'es'
173
- }
174
- return str + 's'
175
- }
176
-
177
- static singularize(str: string): string {
178
- // Simple singularization - in a real implementation you'd use a proper library
179
- if (str.endsWith('ies')) {
180
- return str.slice(0, -3) + 'y'
181
- }
182
- if (str.endsWith('es')) {
183
- return str.slice(0, -2)
184
- }
185
- if (str.endsWith('s') && !str.endsWith('ss')) {
186
- return str.slice(0, -1)
187
- }
188
- return str
189
- }
190
- }
191
-
1
+ import { existsSync } from "fs"
2
+ import { join } from "path"
3
+
4
+ export class GeneratorUtils {
5
+ static validateName(name: string): { valid: boolean; error?: string } {
6
+ if (!name || typeof name !== 'string') {
7
+ return { valid: false, error: 'Name is required' }
8
+ }
9
+
10
+ const trimmed = name.trim()
11
+ if (trimmed.length === 0) {
12
+ return { valid: false, error: 'Name cannot be empty' }
13
+ }
14
+
15
+ if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmed)) {
16
+ return { valid: false, error: 'Name must start with a letter and contain only letters, numbers, hyphens, and underscores' }
17
+ }
18
+
19
+ if (trimmed.length > 100) {
20
+ return { valid: false, error: 'Name must be less than 100 characters' }
21
+ }
22
+
23
+ return { valid: true }
24
+ }
25
+
26
+ static validatePath(path: string): { valid: boolean; error?: string } {
27
+ if (!path || typeof path !== 'string') {
28
+ return { valid: true } // Path is optional
29
+ }
30
+
31
+ const trimmed = path.trim()
32
+ if (trimmed.length === 0) {
33
+ return { valid: true }
34
+ }
35
+
36
+ // Check for invalid characters
37
+ if (/[<>:"|?*]/.test(trimmed)) {
38
+ return { valid: false, error: 'Path contains invalid characters' }
39
+ }
40
+
41
+ // Check for absolute paths (should be relative)
42
+ if (trimmed.startsWith('/') || /^[a-zA-Z]:/.test(trimmed)) {
43
+ return { valid: false, error: 'Path should be relative to project root' }
44
+ }
45
+
46
+ return { valid: true }
47
+ }
48
+
49
+ static checkFileExists(workingDir: string, filePath: string): boolean {
50
+ const fullPath = join(workingDir, filePath)
51
+ return existsSync(fullPath)
52
+ }
53
+
54
+ static getDefaultPath(type: string, name: string): string {
55
+ const kebabName = this.toKebabCase(name)
56
+ const pascalName = this.toPascalCase(name)
57
+
58
+ switch (type) {
59
+ case 'controller':
60
+ return `app/server/controllers/${kebabName}.controller.ts`
61
+ case 'service':
62
+ return `app/server/services/${kebabName}.service.ts`
63
+ case 'route':
64
+ return `app/server/routes/${kebabName}.routes.ts`
65
+ case 'component':
66
+ return `app/client/src/components/${pascalName}/${pascalName}.tsx`
67
+ default:
68
+ return `${kebabName}.ts`
69
+ }
70
+ }
71
+
72
+ static getRelatedFiles(type: string, name: string): string[] {
73
+ const kebabName = this.toKebabCase(name)
74
+ const pascalName = this.toPascalCase(name)
75
+
76
+ switch (type) {
77
+ case 'controller':
78
+ return [
79
+ `app/server/services/${kebabName}.service.ts`,
80
+ `app/server/schemas/${kebabName}.schema.ts`,
81
+ `app/server/routes/${kebabName}.routes.ts`
82
+ ]
83
+ case 'service':
84
+ return [
85
+ `app/server/repositories/${kebabName}.repository.ts`,
86
+ `app/server/controllers/${kebabName}.controller.ts`
87
+ ]
88
+ case 'component':
89
+ return [
90
+ `app/client/src/components/${pascalName}/${pascalName}.css`,
91
+ `app/client/src/components/${pascalName}/index.ts`,
92
+ `app/client/src/components/${pascalName}/${pascalName}.test.tsx`,
93
+ `app/client/src/components/${pascalName}/${pascalName}.stories.tsx`
94
+ ]
95
+ case 'route':
96
+ return [
97
+ `app/server/controllers/${kebabName}.controller.ts`,
98
+ `app/server/middleware/${kebabName}.middleware.ts`
99
+ ]
100
+ default:
101
+ return []
102
+ }
103
+ }
104
+
105
+ static formatFileSize(bytes: number): string {
106
+ const units = ['B', 'KB', 'MB', 'GB']
107
+ let size = bytes
108
+ let unitIndex = 0
109
+
110
+ while (size >= 1024 && unitIndex < units.length - 1) {
111
+ size /= 1024
112
+ unitIndex++
113
+ }
114
+
115
+ return `${size.toFixed(1)} ${units[unitIndex]}`
116
+ }
117
+
118
+ static getTemplateVariables(name: string, additionalVars: Record<string, any> = {}): Record<string, any> {
119
+ return {
120
+ name,
121
+ Name: this.capitalize(name),
122
+ NAME: name.toUpperCase(),
123
+ kebabName: this.toKebabCase(name),
124
+ camelName: this.toCamelCase(name),
125
+ pascalName: this.toPascalCase(name),
126
+ snakeName: this.toSnakeCase(name),
127
+ timestamp: new Date().toISOString(),
128
+ date: new Date().toLocaleDateString(),
129
+ time: new Date().toLocaleTimeString(),
130
+ year: new Date().getFullYear(),
131
+ month: new Date().getMonth() + 1,
132
+ day: new Date().getDate(),
133
+ ...additionalVars
134
+ }
135
+ }
136
+
137
+ // String transformation utilities
138
+ static capitalize(str: string): string {
139
+ return str.charAt(0).toUpperCase() + str.slice(1)
140
+ }
141
+
142
+ static toCamelCase(str: string): string {
143
+ return str
144
+ .replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
145
+ .replace(/^[A-Z]/, char => char.toLowerCase())
146
+ }
147
+
148
+ static toPascalCase(str: string): string {
149
+ return this.capitalize(this.toCamelCase(str))
150
+ }
151
+
152
+ static toKebabCase(str: string): string {
153
+ return str
154
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
155
+ .replace(/[\s_]+/g, '-')
156
+ .toLowerCase()
157
+ }
158
+
159
+ static toSnakeCase(str: string): string {
160
+ return str
161
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
162
+ .replace(/[\s-]+/g, '_')
163
+ .toLowerCase()
164
+ }
165
+
166
+ static pluralize(str: string): string {
167
+ // Simple pluralization - in a real implementation you'd use a proper library
168
+ if (str.endsWith('y')) {
169
+ return str.slice(0, -1) + 'ies'
170
+ }
171
+ if (str.endsWith('s') || str.endsWith('sh') || str.endsWith('ch') || str.endsWith('x') || str.endsWith('z')) {
172
+ return str + 'es'
173
+ }
174
+ return str + 's'
175
+ }
176
+
177
+ static singularize(str: string): string {
178
+ // Simple singularization - in a real implementation you'd use a proper library
179
+ if (str.endsWith('ies')) {
180
+ return str.slice(0, -3) + 'y'
181
+ }
182
+ if (str.endsWith('es')) {
183
+ return str.slice(0, -2)
184
+ }
185
+ if (str.endsWith('s') && !str.endsWith('ss')) {
186
+ return str.slice(0, -1)
187
+ }
188
+ return str
189
+ }
190
+ }
191
+
192
192
  export const generatorUtils = GeneratorUtils
package/core/cli/index.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  import { cliRegistry } from "./command-registry"
9
9
  import { pluginDiscovery } from "./plugin-discovery"
10
10
  import { generateCommand, interactiveGenerateCommand } from "./generators/index"
11
+ import { buildLogger } from "@core/utils/build-logger"
11
12
 
12
13
  // Import modular commands
13
14
  import { builtInCommands } from "./commands"
@@ -51,7 +52,7 @@ async function registerBuiltInCommands() {
51
52
  handler: async (args, options, context) => {
52
53
  const { createPluginAddCommand } = await import('./commands/plugin-add')
53
54
  const cmd = createPluginAddCommand()
54
- await cmd.parseAsync(['node', 'cli', ...args], { from: 'user' })
55
+ await cmd.parseAsync(['node', 'cli', ...args.map(String)], { from: 'user' })
55
56
  }
56
57
  })
57
58
 
@@ -80,7 +81,7 @@ async function registerBuiltInCommands() {
80
81
  handler: async (args, options, context) => {
81
82
  const { createPluginRemoveCommand } = await import('./commands/plugin-remove')
82
83
  const cmd = createPluginRemoveCommand()
83
- await cmd.parseAsync(['node', 'cli', ...args], { from: 'user' })
84
+ await cmd.parseAsync(['node', 'cli', ...args.map(String)], { from: 'user' })
84
85
  }
85
86
  })
86
87
 
@@ -106,7 +107,7 @@ async function registerBuiltInCommands() {
106
107
  handler: async (args, options, context) => {
107
108
  const { createPluginListCommand } = await import('./commands/plugin-list')
108
109
  const cmd = createPluginListCommand()
109
- await cmd.parseAsync(['node', 'cli', ...args], { from: 'user' })
110
+ await cmd.parseAsync(['node', 'cli', ...args.map(String)], { from: 'user' })
110
111
  }
111
112
  })
112
113
 
@@ -116,7 +117,7 @@ async function registerBuiltInCommands() {
116
117
  category: 'Plugins',
117
118
  handler: async (args, options, context) => {
118
119
  if (args.length === 0) {
119
- console.log(`
120
+ buildLogger.info(`
120
121
  ⚡ FluxStack Plugin Dependencies Manager
121
122
 
122
123
  Usage:
@@ -134,7 +135,7 @@ Examples:
134
135
  }
135
136
 
136
137
  const subcommand = args[0]
137
- const subArgs = args.slice(1)
138
+ const subArgs = args.slice(1).map(String)
138
139
 
139
140
  const { createPluginDepsCommand } = await import('./commands/plugin-deps')
140
141
  const cmd = createPluginDepsCommand()
@@ -165,8 +166,8 @@ Examples:
165
166
  }
166
167
  break
167
168
  default:
168
- console.error(`❌ Unknown subcommand: ${subcommand}`)
169
- console.error('Available subcommands: install, list, check, clean')
169
+ buildLogger.error(`❌ Unknown subcommand: ${subcommand}`)
170
+ buildLogger.error('Available subcommands: install, list, check, clean')
170
171
  }
171
172
  }
172
173
  })
@@ -187,6 +188,6 @@ async function main() {
187
188
  }
188
189
 
189
190
  main().catch((error) => {
190
- console.error('CLI Error:', error)
191
+ buildLogger.error('CLI Error:', error)
191
192
  process.exit(1)
192
193
  })
@@ -74,7 +74,7 @@ export class CliPluginDiscovery {
74
74
  try {
75
75
  const pluginModule = await import(pluginPath)
76
76
  const plugin = pluginModule.default || Object.values(pluginModule).find(
77
- (exp: any) => exp && typeof exp === 'object' && exp.name && exp.commands
77
+ (exp: unknown) => exp && typeof exp === 'object' && (exp as Record<string, unknown>).name && (exp as Record<string, unknown>).commands
78
78
  ) as Plugin
79
79
 
80
80
  if (plugin && plugin.commands) {
@@ -93,7 +93,7 @@ export class CliPluginDiscovery {
93
93
  try {
94
94
  const pluginModule = await import(pluginIndexPath)
95
95
  const plugin = pluginModule.default || Object.values(pluginModule).find(
96
- (exp: any) => exp && typeof exp === 'object' && exp.name && exp.commands
96
+ (exp: unknown) => exp && typeof exp === 'object' && (exp as Record<string, unknown>).name && (exp as Record<string, unknown>).commands
97
97
  ) as Plugin
98
98
 
99
99
  if (plugin && plugin.commands) {
@@ -1,49 +1,49 @@
1
- /**
2
- * Authentication Hook
3
- * Core FluxStack authentication utilities
4
- */
5
-
6
- import type { BaseUser, BaseUserStore } from '../state/index'
7
-
8
- /**
9
- * Create authentication hook for a user store
10
- */
11
- export function createAuthHook(useUserStore: () => BaseUserStore) {
12
- return function useAuth() {
13
- const store = useUserStore()
14
-
15
- return {
16
- // State
17
- currentUser: store.currentUser,
18
- isAuthenticated: store.isAuthenticated,
19
- isLoading: store.isLoading,
20
- error: store.error,
21
-
22
- // Computed
23
- isAdmin: store.currentUser?.role === 'admin',
24
-
25
- // Actions
26
- login: store.login,
27
- register: store.register,
28
- logout: store.logout,
29
- updateProfile: store.updateProfile,
30
- clearError: store.clearError
31
- }
32
- }
33
- }
34
-
35
- /**
36
- * Base auth hook interface
37
- */
38
- export interface AuthHook {
39
- currentUser: BaseUser | null
40
- isAuthenticated: boolean
41
- isLoading: boolean
42
- error: string | null
43
- isAdmin: boolean
44
- login: (credentials: { email: string; password: string }) => Promise<void>
45
- register: (data: { email: string; password: string; name: string }) => Promise<void>
46
- logout: () => void
47
- updateProfile: (data: Partial<BaseUser>) => Promise<void>
48
- clearError: () => void
1
+ /**
2
+ * Authentication Hook
3
+ * Core FluxStack authentication utilities
4
+ */
5
+
6
+ import type { BaseUser, BaseUserStore } from '../state/index'
7
+
8
+ /**
9
+ * Create authentication hook for a user store
10
+ */
11
+ export function createAuthHook(useUserStore: () => BaseUserStore) {
12
+ return function useAuth() {
13
+ const store = useUserStore()
14
+
15
+ return {
16
+ // State
17
+ currentUser: store.currentUser,
18
+ isAuthenticated: store.isAuthenticated,
19
+ isLoading: store.isLoading,
20
+ error: store.error,
21
+
22
+ // Computed
23
+ isAdmin: store.currentUser?.role === 'admin',
24
+
25
+ // Actions
26
+ login: store.login,
27
+ register: store.register,
28
+ logout: store.logout,
29
+ updateProfile: store.updateProfile,
30
+ clearError: store.clearError
31
+ }
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Base auth hook interface
37
+ */
38
+ export interface AuthHook {
39
+ currentUser: BaseUser | null
40
+ isAuthenticated: boolean
41
+ isLoading: boolean
42
+ error: string | null
43
+ isAdmin: boolean
44
+ login: (credentials: { email: string; password: string }) => Promise<void>
45
+ register: (data: { email: string; password: string; name: string }) => Promise<void>
46
+ logout: () => void
47
+ updateProfile: (data: Partial<BaseUser>) => Promise<void>
48
+ clearError: () => void
49
49
  }
@@ -5,19 +5,20 @@
5
5
 
6
6
  import { clientConfig } from '@config'
7
7
  import type { LogLevel } from 'vite'
8
+ import { buildLogger } from "../utils/build-logger"
8
9
 
9
10
  type ViteDevServer = Awaited<ReturnType<typeof import('vite')['createServer']>>
10
11
 
11
12
  let viteServer: ViteDevServer | null = null
12
13
 
13
- export const startFrontendOnly = async (config: any = {}) => {
14
- const port = config.vitePort || clientConfig.vite.port || 5173
15
- const host = config.viteHost || clientConfig.vite.host || 'localhost'
14
+ export const startFrontendOnly = async (config: Record<string, unknown> = {}) => {
15
+ const port = (config.vitePort ?? clientConfig.vite.port ?? 5173) as number
16
+ const host = (config.viteHost ?? clientConfig.vite.host ?? 'localhost') as string
16
17
  const logLevel = (config.logLevel || clientConfig.vite.logLevel || 'info') as LogLevel
17
18
 
18
- console.log(`⚛️ FluxStack Frontend Only`)
19
- console.log(`🌐 http://${host}:${port}`)
20
- console.log()
19
+ buildLogger.info(`⚛️ FluxStack Frontend Only`)
20
+ buildLogger.info(`🌐 http://${host}:${port}`)
21
+ buildLogger.info('')
21
22
 
22
23
  try {
23
24
  // Dynamic import of vite
@@ -29,20 +30,20 @@ export const startFrontendOnly = async (config: any = {}) => {
29
30
  server: {
30
31
  port,
31
32
  host,
32
- strictPort: clientConfig.vite.strictPort
33
+ strictPort: clientConfig.vite.strictPort as boolean | undefined
33
34
  },
34
35
  logLevel
35
36
  })
36
37
 
37
38
  await viteServer.listen()
38
39
 
39
- console.log(`✅ Frontend server ready!`)
40
- console.log()
40
+ buildLogger.success(`✅ Frontend server ready!`)
41
+ buildLogger.info('')
41
42
 
42
43
  // Setup cleanup on process exit
43
44
  const cleanup = async () => {
44
45
  if (viteServer) {
45
- console.log('\n🛑 Stopping frontend...')
46
+ buildLogger.info('\n🛑 Stopping frontend...')
46
47
  await viteServer.close()
47
48
  viteServer = null
48
49
  process.exit(0)
@@ -63,15 +64,15 @@ export const startFrontendOnly = async (config: any = {}) => {
63
64
  (errorMessage.includes('Port') && errorMessage.includes('is in use'))
64
65
 
65
66
  if (isPortInUse) {
66
- console.error(`❌ Failed to start Vite: Port ${port} is already in use`)
67
- console.log(`💡 Try one of these solutions:`)
68
- console.log(` 1. Stop the process using port ${port}`)
69
- console.log(` 2. Change VITE_PORT in your .env file`)
70
- console.log(` 3. Kill the process: ${process.platform === 'win32' ? `netstat -ano | findstr :${port}` : `lsof -ti:${port} | xargs kill -9`}`)
67
+ buildLogger.error(`❌ Failed to start Vite: Port ${port} is already in use`)
68
+ buildLogger.info(`💡 Try one of these solutions:`)
69
+ buildLogger.info(` 1. Stop the process using port ${port}`)
70
+ buildLogger.info(` 2. Change VITE_PORT in your .env file`)
71
+ buildLogger.info(` 3. Kill the process: ${process.platform === 'win32' ? `netstat -ano | findstr :${port}` : `lsof -ti:${port} | xargs kill -9`}`)
71
72
  process.exit(1)
72
73
  } else {
73
- console.error('❌ Failed to start Vite server:', errorMessage)
74
- console.error('Full error:', error)
74
+ buildLogger.error('❌ Failed to start Vite server:', errorMessage)
75
+ buildLogger.error('Full error:', error)
75
76
  process.exit(1)
76
77
  }
77
78
  }