create-fluxstack 1.0.0 → 1.0.2

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 (101) hide show
  1. package/create-fluxstack.ts +32 -17
  2. package/package-template.json +51 -0
  3. package/package.json +2 -1
  4. package/.env +0 -30
  5. package/LICENSE +0 -21
  6. package/app/client/README.md +0 -69
  7. package/app/client/frontend-only.ts +0 -12
  8. package/app/client/index.html +0 -13
  9. package/app/client/public/vite.svg +0 -1
  10. package/app/client/src/App.css +0 -883
  11. package/app/client/src/App.tsx +0 -669
  12. package/app/client/src/assets/react.svg +0 -1
  13. package/app/client/src/components/TestPage.tsx +0 -453
  14. package/app/client/src/index.css +0 -51
  15. package/app/client/src/lib/eden-api.ts +0 -110
  16. package/app/client/src/main.tsx +0 -10
  17. package/app/client/src/vite-env.d.ts +0 -1
  18. package/app/client/tsconfig.app.json +0 -43
  19. package/app/client/tsconfig.json +0 -7
  20. package/app/client/tsconfig.node.json +0 -25
  21. package/app/server/app.ts +0 -10
  22. package/app/server/backend-only.ts +0 -15
  23. package/app/server/controllers/users.controller.ts +0 -69
  24. package/app/server/index.ts +0 -104
  25. package/app/server/routes/index.ts +0 -25
  26. package/app/server/routes/users.routes.ts +0 -121
  27. package/app/server/types/index.ts +0 -1
  28. package/app/shared/types/index.ts +0 -18
  29. package/bun.lock +0 -1053
  30. package/core/__tests__/integration.test.ts +0 -227
  31. package/core/build/index.ts +0 -186
  32. package/core/cli/command-registry.ts +0 -334
  33. package/core/cli/index.ts +0 -394
  34. package/core/cli/plugin-discovery.ts +0 -200
  35. package/core/client/standalone.ts +0 -57
  36. package/core/config/__tests__/config-loader.test.ts +0 -591
  37. package/core/config/__tests__/config-merger.test.ts +0 -657
  38. package/core/config/__tests__/env-converter.test.ts +0 -372
  39. package/core/config/__tests__/env-processor.test.ts +0 -431
  40. package/core/config/__tests__/env.test.ts +0 -452
  41. package/core/config/__tests__/integration.test.ts +0 -418
  42. package/core/config/__tests__/loader.test.ts +0 -331
  43. package/core/config/__tests__/schema.test.ts +0 -129
  44. package/core/config/__tests__/validator.test.ts +0 -318
  45. package/core/config/env-dynamic.ts +0 -326
  46. package/core/config/env.ts +0 -597
  47. package/core/config/index.ts +0 -317
  48. package/core/config/loader.ts +0 -546
  49. package/core/config/runtime-config.ts +0 -322
  50. package/core/config/schema.ts +0 -694
  51. package/core/config/validator.ts +0 -540
  52. package/core/framework/__tests__/server.test.ts +0 -233
  53. package/core/framework/client.ts +0 -132
  54. package/core/framework/index.ts +0 -8
  55. package/core/framework/server.ts +0 -501
  56. package/core/framework/types.ts +0 -63
  57. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  58. package/core/plugins/__tests__/manager.test.ts +0 -398
  59. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  60. package/core/plugins/__tests__/registry.test.ts +0 -335
  61. package/core/plugins/built-in/index.ts +0 -142
  62. package/core/plugins/built-in/logger/index.ts +0 -180
  63. package/core/plugins/built-in/monitoring/README.md +0 -193
  64. package/core/plugins/built-in/monitoring/index.ts +0 -912
  65. package/core/plugins/built-in/static/index.ts +0 -289
  66. package/core/plugins/built-in/swagger/index.ts +0 -229
  67. package/core/plugins/built-in/vite/index.ts +0 -316
  68. package/core/plugins/config.ts +0 -348
  69. package/core/plugins/discovery.ts +0 -350
  70. package/core/plugins/executor.ts +0 -351
  71. package/core/plugins/index.ts +0 -195
  72. package/core/plugins/manager.ts +0 -583
  73. package/core/plugins/registry.ts +0 -424
  74. package/core/plugins/types.ts +0 -254
  75. package/core/server/framework.ts +0 -123
  76. package/core/server/index.ts +0 -8
  77. package/core/server/plugins/database.ts +0 -182
  78. package/core/server/plugins/logger.ts +0 -47
  79. package/core/server/plugins/swagger.ts +0 -34
  80. package/core/server/standalone.ts +0 -91
  81. package/core/templates/create-project.ts +0 -455
  82. package/core/types/api.ts +0 -169
  83. package/core/types/build.ts +0 -174
  84. package/core/types/config.ts +0 -68
  85. package/core/types/index.ts +0 -127
  86. package/core/types/plugin.ts +0 -94
  87. package/core/utils/__tests__/errors.test.ts +0 -139
  88. package/core/utils/__tests__/helpers.test.ts +0 -297
  89. package/core/utils/__tests__/logger.test.ts +0 -141
  90. package/core/utils/env-runtime-v2.ts +0 -232
  91. package/core/utils/env-runtime.ts +0 -252
  92. package/core/utils/errors/codes.ts +0 -115
  93. package/core/utils/errors/handlers.ts +0 -63
  94. package/core/utils/errors/index.ts +0 -81
  95. package/core/utils/helpers.ts +0 -180
  96. package/core/utils/index.ts +0 -18
  97. package/core/utils/logger/index.ts +0 -161
  98. package/core/utils/logger.ts +0 -106
  99. package/core/utils/monitoring/index.ts +0 -212
  100. package/tsconfig.json +0 -51
  101. package/vite.config.ts +0 -42
package/core/cli/index.ts DELETED
@@ -1,394 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import { FluxStackBuilder } from "../build"
4
- import { ProjectCreator } from "../templates/create-project"
5
- import { getConfigSync } from "../config"
6
- import { cliRegistry } from "./command-registry"
7
- import { pluginDiscovery } from "./plugin-discovery"
8
-
9
- const command = process.argv[2]
10
- const args = process.argv.slice(3)
11
-
12
- // Register built-in commands
13
- async function registerBuiltInCommands() {
14
- // Help command
15
- cliRegistry.register({
16
- name: 'help',
17
- description: 'Show help information',
18
- category: 'General',
19
- aliases: ['h', '--help', '-h'],
20
- arguments: [
21
- {
22
- name: 'command',
23
- description: 'Command to show help for',
24
- required: false
25
- }
26
- ],
27
- handler: async (args, options, context) => {
28
- if (args[0]) {
29
- const targetCommand = cliRegistry.get(args[0])
30
- if (targetCommand) {
31
- cliRegistry.showCommandHelp(targetCommand)
32
- } else {
33
- console.error(`❌ Unknown command: ${args[0]}`)
34
- cliRegistry.showHelp()
35
- }
36
- } else {
37
- cliRegistry.showHelp()
38
- }
39
- }
40
- })
41
-
42
- // Dev command
43
- cliRegistry.register({
44
- name: 'dev',
45
- description: 'Start full-stack development server',
46
- category: 'Development',
47
- usage: 'flux dev [options]',
48
- examples: [
49
- 'flux dev # Start development server',
50
- 'flux dev --port 4000 # Start on custom port'
51
- ],
52
- options: [
53
- {
54
- name: 'port',
55
- short: 'p',
56
- description: 'Port for backend server',
57
- type: 'number',
58
- default: 3000
59
- },
60
- {
61
- name: 'frontend-port',
62
- description: 'Port for frontend server',
63
- type: 'number',
64
- default: 5173
65
- }
66
- ],
67
- handler: async (args, options, context) => {
68
- console.log("⚡ FluxStack Full-Stack Development")
69
- console.log(`🌐 Frontend: http://localhost:${options['frontend-port']}`)
70
- console.log(`🚀 Backend: http://localhost:${options.port}`)
71
- console.log("🔄 Backend inicia Vite programaticamente - Zero órfãos!")
72
- console.log("📦 Starting backend server...")
73
- console.log()
74
-
75
- const { spawn } = await import("child_process")
76
- const devProcess = spawn("bun", ["--watch", "app/server/index.ts"], {
77
- stdio: "inherit",
78
- cwd: process.cwd(),
79
- env: {
80
- ...process.env,
81
- FRONTEND_PORT: options['frontend-port'].toString(),
82
- BACKEND_PORT: options.port.toString()
83
- }
84
- })
85
-
86
- process.on('SIGINT', () => {
87
- console.log('\n🛑 Shutting down gracefully...')
88
- devProcess.kill('SIGTERM')
89
- setTimeout(() => {
90
- devProcess.kill('SIGKILL')
91
- process.exit(0)
92
- }, 5000)
93
- })
94
-
95
- devProcess.on('close', (code) => {
96
- process.exit(code || 0)
97
- })
98
-
99
- // Keep the CLI running until the child process exits
100
- return new Promise((resolve) => {
101
- devProcess.on('exit', resolve)
102
- })
103
- }
104
- })
105
-
106
- // Build command
107
- cliRegistry.register({
108
- name: 'build',
109
- description: 'Build the application for production',
110
- category: 'Build',
111
- usage: 'flux build [options]',
112
- examples: [
113
- 'flux build # Build both frontend and backend',
114
- 'flux build --frontend-only # Build only frontend',
115
- 'flux build --backend-only # Build only backend'
116
- ],
117
- options: [
118
- {
119
- name: 'frontend-only',
120
- description: 'Build only frontend',
121
- type: 'boolean'
122
- },
123
- {
124
- name: 'backend-only',
125
- description: 'Build only backend',
126
- type: 'boolean'
127
- },
128
- {
129
- name: 'production',
130
- description: 'Build for production (minified)',
131
- type: 'boolean',
132
- default: true
133
- }
134
- ],
135
- handler: async (args, options, context) => {
136
- const config = getConfigSync()
137
- const builder = new FluxStackBuilder(config)
138
-
139
- if (options['frontend-only']) {
140
- await builder.buildClient()
141
- } else if (options['backend-only']) {
142
- await builder.buildServer()
143
- } else {
144
- await builder.build()
145
- }
146
- }
147
- })
148
-
149
- // Create command
150
- cliRegistry.register({
151
- name: 'create',
152
- description: 'Create a new FluxStack project',
153
- category: 'Project',
154
- usage: 'flux create <project-name> [template]',
155
- examples: [
156
- 'flux create my-app # Create basic project',
157
- 'flux create my-app full # Create full-featured project'
158
- ],
159
- arguments: [
160
- {
161
- name: 'project-name',
162
- description: 'Name of the project to create',
163
- required: true,
164
- type: 'string'
165
- },
166
- {
167
- name: 'template',
168
- description: 'Project template to use',
169
- required: false,
170
- type: 'string',
171
- default: 'basic',
172
- choices: ['basic', 'full']
173
- }
174
- ],
175
- handler: async (args, options, context) => {
176
- const [projectName, template] = args
177
-
178
- if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
179
- console.error("❌ Project name can only contain letters, numbers, hyphens, and underscores")
180
- return
181
- }
182
-
183
- try {
184
- const creator = new ProjectCreator({
185
- name: projectName,
186
- template: template as 'basic' | 'full' || 'basic'
187
- })
188
-
189
- await creator.create()
190
- } catch (error) {
191
- console.error("❌ Failed to create project:", error instanceof Error ? error.message : String(error))
192
- throw error
193
- }
194
- }
195
- })
196
- }
197
-
198
- // Main CLI logic
199
- async function main() {
200
- // Register built-in commands
201
- await registerBuiltInCommands()
202
-
203
- // Discover and register plugin commands
204
- await pluginDiscovery.discoverAndRegisterCommands()
205
-
206
- // Handle special cases first
207
- if (!command || command === 'help' || command === '--help' || command === '-h') {
208
- await cliRegistry.execute('help', args)
209
- return
210
- }
211
-
212
- // Check if it's a registered command (built-in or plugin)
213
- if (cliRegistry.has(command)) {
214
- const exitCode = await cliRegistry.execute(command, args)
215
- process.exit(exitCode)
216
- return
217
- }
218
-
219
- // Fallback to legacy command handling for backward compatibility
220
- await handleLegacyCommands()
221
- }
222
-
223
- // Legacy command handling for backward compatibility
224
- async function handleLegacyCommands() {
225
- switch (command) {
226
- case "dev":
227
- console.log("⚡ FluxStack Full-Stack Development")
228
- console.log("🌐 Frontend: http://localhost:5173")
229
- console.log("🚀 Backend: http://localhost:3000")
230
- console.log("🔄 Backend inicia Vite programaticamente - Zero órfãos!")
231
- console.log("📦 Starting backend server...")
232
- console.log()
233
-
234
- // Start only backend - it will start Vite programmatically
235
- const { spawn } = await import("child_process")
236
- const devProcess = spawn("bun", ["--watch", "app/server/index.ts"], {
237
- stdio: "inherit",
238
- cwd: process.cwd()
239
- })
240
-
241
- // Handle process cleanup
242
- process.on('SIGINT', () => {
243
- console.log('\n🛑 Shutting down gracefully...')
244
- devProcess.kill('SIGTERM')
245
- setTimeout(() => {
246
- devProcess.kill('SIGKILL')
247
- process.exit(0)
248
- }, 5000)
249
- })
250
-
251
- devProcess.on('close', (code) => {
252
- process.exit(code || 0)
253
- })
254
-
255
- // Keep the CLI running until the child process exits
256
- await new Promise((resolve) => {
257
- devProcess.on('exit', resolve)
258
- })
259
- break
260
-
261
- case "frontend":
262
- console.log("🎨 FluxStack Frontend Development")
263
- console.log("🌐 Frontend: http://localhost:5173")
264
- console.log("📦 Starting Vite dev server...")
265
- console.log()
266
-
267
- const { spawn: spawnFrontend } = await import("child_process")
268
- const frontendProcess = spawnFrontend("vite", ["--config", "vite.config.ts"], {
269
- stdio: "inherit",
270
- cwd: process.cwd()
271
- })
272
-
273
- process.on('SIGINT', () => {
274
- frontendProcess.kill('SIGINT')
275
- process.exit(0)
276
- })
277
- break
278
-
279
- case "backend":
280
- console.log("⚡ FluxStack Backend Development")
281
- console.log("🚀 API Server: http://localhost:3001")
282
- console.log("📦 Starting backend with hot reload...")
283
- console.log()
284
-
285
- // Start backend with Bun watch for hot reload
286
- const { spawn: spawnBackend } = await import("child_process")
287
- const backendProcess = spawnBackend("bun", ["--watch", "app/server/backend-only.ts"], {
288
- stdio: "inherit",
289
- cwd: process.cwd()
290
- })
291
-
292
- // Handle process cleanup
293
- process.on('SIGINT', () => {
294
- backendProcess.kill('SIGINT')
295
- process.exit(0)
296
- })
297
- break
298
-
299
- case "build":
300
- const config = getConfigSync()
301
- const builder = new FluxStackBuilder(config)
302
- await builder.build()
303
- break
304
-
305
- case "build:frontend":
306
- const frontendConfig = getConfigSync()
307
- const frontendBuilder = new FluxStackBuilder(frontendConfig)
308
- await frontendBuilder.buildClient()
309
- break
310
-
311
- case "build:backend":
312
- const backendConfig = getConfigSync()
313
- const backendBuilder = new FluxStackBuilder(backendConfig)
314
- await backendBuilder.buildServer()
315
- break
316
-
317
- case "start":
318
- console.log("🚀 Starting FluxStack production server...")
319
- await import(process.cwd() + "/dist/index.js")
320
- break
321
-
322
- case "create":
323
- const projectName = process.argv[3]
324
- const template = process.argv[4]
325
-
326
- if (!projectName) {
327
- console.error("❌ Please provide a project name: flux create my-app")
328
- console.error()
329
- console.error("Usage:")
330
- console.error(" flux create <project-name> [template]")
331
- console.error()
332
- console.error("Templates:")
333
- console.error(" basic Basic FluxStack project (default)")
334
- console.error(" full Full-featured project with examples")
335
- process.exit(1)
336
- }
337
-
338
- // Validate project name
339
- if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
340
- console.error("❌ Project name can only contain letters, numbers, hyphens, and underscores")
341
- process.exit(1)
342
- }
343
-
344
- try {
345
- const creator = new ProjectCreator({
346
- name: projectName,
347
- template: template as 'basic' | 'full' || 'basic'
348
- })
349
-
350
- await creator.create()
351
- } catch (error) {
352
- console.error("❌ Failed to create project:", error instanceof Error ? error.message : String(error))
353
- process.exit(1)
354
- }
355
- break
356
-
357
- default:
358
- console.log(`
359
- ⚡ FluxStack Framework CLI
360
-
361
- Usage:
362
- flux dev Start full-stack development server
363
- flux frontend Start frontend only (Vite dev server)
364
- flux backend Start backend only (API server)
365
- flux build Build both frontend and backend
366
- flux build:frontend Build frontend only
367
- flux build:backend Build backend only
368
- flux start Start production server
369
- flux create Create new project
370
-
371
- Examples:
372
- flux dev # Full-stack development
373
- flux frontend # Frontend only (port 5173)
374
- flux backend # Backend only (port 3001)
375
- flux create my-app # Create new project
376
-
377
- Alternative commands:
378
- fluxstack dev # Same as flux dev
379
- bun run dev:frontend # Direct frontend start
380
- bun run dev:backend # Direct backend start
381
-
382
- Environment Variables:
383
- FRONTEND_PORT=5173 # Frontend port
384
- BACKEND_PORT=3001 # Backend port
385
- API_URL=http://localhost:3001 # API URL for frontend
386
- `)
387
- }
388
- }
389
-
390
- // Run main CLI
391
- main().catch(error => {
392
- console.error('❌ CLI Error:', error instanceof Error ? error.message : String(error))
393
- process.exit(1)
394
- })
@@ -1,200 +0,0 @@
1
- import { existsSync } from 'fs'
2
- import { join } from 'path'
3
- import type { Plugin } from '../plugins/types'
4
- import { cliRegistry } from './command-registry'
5
- import { logger } from '../utils/logger'
6
-
7
- export class CliPluginDiscovery {
8
- private loadedPlugins = new Set<string>()
9
-
10
- async discoverAndRegisterCommands(): Promise<void> {
11
- // 1. Load built-in plugins with CLI commands
12
- await this.loadBuiltInPlugins()
13
-
14
- // 2. Load external plugins from node_modules
15
- await this.loadExternalPlugins()
16
-
17
- // 3. Load local plugins from project
18
- await this.loadLocalPlugins()
19
- }
20
-
21
- private async loadBuiltInPlugins(): Promise<void> {
22
- const builtInPluginsDir = join(__dirname, '../server/plugins')
23
-
24
- if (!existsSync(builtInPluginsDir)) {
25
- return
26
- }
27
-
28
- try {
29
- // For now, we'll manually list built-in plugins that might have CLI commands
30
- const potentialPlugins = [
31
- 'logger',
32
- 'vite',
33
- 'swagger',
34
- 'static',
35
- 'database'
36
- ]
37
-
38
- for (const pluginName of potentialPlugins) {
39
- try {
40
- const pluginPath = join(builtInPluginsDir, `${pluginName}.ts`)
41
- if (existsSync(pluginPath)) {
42
- const pluginModule = await import(pluginPath)
43
- const plugin = pluginModule[`${pluginName}Plugin`] as Plugin
44
-
45
- if (plugin && plugin.commands) {
46
- this.registerPluginCommands(plugin)
47
- }
48
- }
49
- } catch (error) {
50
- logger.debug(`Failed to load built-in plugin ${pluginName}:`, error)
51
- }
52
- }
53
- } catch (error) {
54
- logger.debug('Failed to scan built-in plugins:', error)
55
- }
56
- }
57
-
58
- private async loadExternalPlugins(): Promise<void> {
59
- const nodeModulesDir = join(process.cwd(), 'node_modules')
60
-
61
- if (!existsSync(nodeModulesDir)) {
62
- return
63
- }
64
-
65
- try {
66
- const fs = await import('fs')
67
- const entries = fs.readdirSync(nodeModulesDir, { withFileTypes: true })
68
-
69
- for (const entry of entries) {
70
- if (!entry.isDirectory()) continue
71
-
72
- // Check for FluxStack plugins (convention: fluxstack-plugin-*)
73
- if (entry.name.startsWith('fluxstack-plugin-')) {
74
- await this.loadExternalPlugin(entry.name)
75
- }
76
-
77
- // Check for scoped packages (@fluxstack/plugin-*)
78
- if (entry.name.startsWith('@fluxstack')) {
79
- const scopedDir = join(nodeModulesDir, entry.name)
80
- if (existsSync(scopedDir)) {
81
- const scopedEntries = fs.readdirSync(scopedDir, { withFileTypes: true })
82
- for (const scopedEntry of scopedEntries) {
83
- if (scopedEntry.isDirectory() && scopedEntry.name.startsWith('plugin-')) {
84
- await this.loadExternalPlugin(`${entry.name}/${scopedEntry.name}`)
85
- }
86
- }
87
- }
88
- }
89
- }
90
- } catch (error) {
91
- logger.debug('Failed to scan external plugins:', error)
92
- }
93
- }
94
-
95
- private async loadExternalPlugin(packageName: string): Promise<void> {
96
- try {
97
- const packagePath = join(process.cwd(), 'node_modules', packageName)
98
- const packageJsonPath = join(packagePath, 'package.json')
99
-
100
- if (!existsSync(packageJsonPath)) {
101
- return
102
- }
103
-
104
- const packageJson = JSON.parse(await import('fs').then(fs =>
105
- fs.readFileSync(packageJsonPath, 'utf-8')
106
- ))
107
-
108
- // Check if this is a FluxStack plugin
109
- if (packageJson.fluxstack?.plugin) {
110
- const entryPoint = packageJson.main || 'index.js'
111
- const pluginPath = join(packagePath, entryPoint)
112
-
113
- if (existsSync(pluginPath)) {
114
- const pluginModule = await import(pluginPath)
115
- const plugin = pluginModule.default || pluginModule[packageJson.fluxstack.plugin] as Plugin
116
-
117
- if (plugin && plugin.commands) {
118
- this.registerPluginCommands(plugin)
119
- }
120
- }
121
- }
122
- } catch (error) {
123
- logger.debug(`Failed to load external plugin ${packageName}:`, error)
124
- }
125
- }
126
-
127
- private async loadLocalPlugins(): Promise<void> {
128
- const localPluginsDir = join(process.cwd(), 'plugins')
129
-
130
- if (!existsSync(localPluginsDir)) {
131
- return
132
- }
133
-
134
- try {
135
- const fs = await import('fs')
136
- const entries = fs.readdirSync(localPluginsDir, { withFileTypes: true })
137
-
138
- for (const entry of entries) {
139
- if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.js'))) {
140
- const pluginPath = join(localPluginsDir, entry.name)
141
-
142
- try {
143
- const pluginModule = await import(pluginPath)
144
- const plugin = pluginModule.default || Object.values(pluginModule).find(
145
- (exp: any) => exp && typeof exp === 'object' && exp.name && exp.commands
146
- ) as Plugin
147
-
148
- if (plugin && plugin.commands) {
149
- this.registerPluginCommands(plugin)
150
- }
151
- } catch (error) {
152
- logger.debug(`Failed to load local plugin ${entry.name}:`, error)
153
- }
154
- }
155
- }
156
- } catch (error) {
157
- logger.debug('Failed to scan local plugins:', error)
158
- }
159
- }
160
-
161
- private registerPluginCommands(plugin: Plugin): void {
162
- if (!plugin.commands || this.loadedPlugins.has(plugin.name)) {
163
- return
164
- }
165
-
166
- try {
167
- for (const command of plugin.commands) {
168
- // Prefix command with plugin name to avoid conflicts
169
- const prefixedCommand = {
170
- ...command,
171
- name: `${plugin.name}:${command.name}`,
172
- category: command.category || `Plugin: ${plugin.name}`,
173
- aliases: command.aliases?.map(alias => `${plugin.name}:${alias}`)
174
- }
175
-
176
- cliRegistry.register(prefixedCommand)
177
-
178
- // Also register without prefix if no conflict exists
179
- if (!cliRegistry.has(command.name)) {
180
- cliRegistry.register({
181
- ...command,
182
- category: command.category || `Plugin: ${plugin.name}`
183
- })
184
- }
185
- }
186
-
187
- this.loadedPlugins.add(plugin.name)
188
- logger.debug(`Registered ${plugin.commands.length} CLI commands from plugin: ${plugin.name}`)
189
-
190
- } catch (error) {
191
- logger.error(`Failed to register CLI commands for plugin ${plugin.name}:`, error)
192
- }
193
- }
194
-
195
- getLoadedPlugins(): string[] {
196
- return Array.from(this.loadedPlugins)
197
- }
198
- }
199
-
200
- export const pluginDiscovery = new CliPluginDiscovery()
@@ -1,57 +0,0 @@
1
- // Standalone frontend development
2
- import { spawn } from "bun"
3
- import { join } from "path"
4
-
5
- export const startFrontendOnly = (config: any = {}) => {
6
- const clientPath = config.clientPath || "app/client"
7
- const port = config.vitePort || process.env.FRONTEND_PORT || 5173
8
- const apiUrl = config.apiUrl || process.env.API_URL || 'http://localhost:3000/api'
9
-
10
- console.log(`⚛️ FluxStack Frontend`)
11
- console.log(`🌐 http://${process.env.HOST || 'localhost'}:${port}`)
12
- console.log(`🔗 API: ${apiUrl}`)
13
- console.log()
14
-
15
- const viteProcess = spawn({
16
- cmd: ["bun", "run", "dev"],
17
- cwd: join(process.cwd(), clientPath),
18
- stdout: "pipe",
19
- stderr: "pipe",
20
- env: {
21
- ...process.env,
22
- VITE_API_URL: apiUrl,
23
- PORT: port.toString(),
24
- HOST: process.env.HOST || 'localhost'
25
- }
26
- })
27
-
28
- if (viteProcess.stdout) {
29
- viteProcess.stdout.pipeTo(new WritableStream({
30
- write(chunk) {
31
- const output = new TextDecoder().decode(chunk)
32
- // Filtrar mensagens desnecessárias do Vite
33
- if (!output.includes("hmr update") && !output.includes("Local:")) {
34
- console.log(output)
35
- }
36
- }
37
- })).catch(() => {}) // Ignore pipe errors
38
- }
39
-
40
- if (viteProcess.stderr) {
41
- viteProcess.stderr.pipeTo(new WritableStream({
42
- write(chunk) {
43
- const error = new TextDecoder().decode(chunk)
44
- console.error(error)
45
- }
46
- })).catch(() => {}) // Ignore pipe errors
47
- }
48
-
49
- // Cleanup ao sair
50
- process.on("SIGINT", () => {
51
- console.log("\n🛑 Stopping frontend...")
52
- viteProcess.kill()
53
- process.exit(0)
54
- })
55
-
56
- return viteProcess
57
- }