create-fluxstack 1.0.1 → 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 (100) hide show
  1. package/create-fluxstack.ts +2 -3
  2. package/package.json +1 -1
  3. package/.env +0 -30
  4. package/LICENSE +0 -21
  5. package/app/client/README.md +0 -69
  6. package/app/client/frontend-only.ts +0 -12
  7. package/app/client/index.html +0 -13
  8. package/app/client/public/vite.svg +0 -1
  9. package/app/client/src/App.css +0 -883
  10. package/app/client/src/App.tsx +0 -669
  11. package/app/client/src/assets/react.svg +0 -1
  12. package/app/client/src/components/TestPage.tsx +0 -453
  13. package/app/client/src/index.css +0 -51
  14. package/app/client/src/lib/eden-api.ts +0 -110
  15. package/app/client/src/main.tsx +0 -10
  16. package/app/client/src/vite-env.d.ts +0 -1
  17. package/app/client/tsconfig.app.json +0 -43
  18. package/app/client/tsconfig.json +0 -7
  19. package/app/client/tsconfig.node.json +0 -25
  20. package/app/server/app.ts +0 -10
  21. package/app/server/backend-only.ts +0 -15
  22. package/app/server/controllers/users.controller.ts +0 -69
  23. package/app/server/index.ts +0 -104
  24. package/app/server/routes/index.ts +0 -25
  25. package/app/server/routes/users.routes.ts +0 -121
  26. package/app/server/types/index.ts +0 -1
  27. package/app/shared/types/index.ts +0 -18
  28. package/bun.lock +0 -1053
  29. package/core/__tests__/integration.test.ts +0 -227
  30. package/core/build/index.ts +0 -186
  31. package/core/cli/command-registry.ts +0 -334
  32. package/core/cli/index.ts +0 -394
  33. package/core/cli/plugin-discovery.ts +0 -200
  34. package/core/client/standalone.ts +0 -57
  35. package/core/config/__tests__/config-loader.test.ts +0 -591
  36. package/core/config/__tests__/config-merger.test.ts +0 -657
  37. package/core/config/__tests__/env-converter.test.ts +0 -372
  38. package/core/config/__tests__/env-processor.test.ts +0 -431
  39. package/core/config/__tests__/env.test.ts +0 -452
  40. package/core/config/__tests__/integration.test.ts +0 -418
  41. package/core/config/__tests__/loader.test.ts +0 -331
  42. package/core/config/__tests__/schema.test.ts +0 -129
  43. package/core/config/__tests__/validator.test.ts +0 -318
  44. package/core/config/env-dynamic.ts +0 -326
  45. package/core/config/env.ts +0 -597
  46. package/core/config/index.ts +0 -317
  47. package/core/config/loader.ts +0 -546
  48. package/core/config/runtime-config.ts +0 -322
  49. package/core/config/schema.ts +0 -694
  50. package/core/config/validator.ts +0 -540
  51. package/core/framework/__tests__/server.test.ts +0 -233
  52. package/core/framework/client.ts +0 -132
  53. package/core/framework/index.ts +0 -8
  54. package/core/framework/server.ts +0 -501
  55. package/core/framework/types.ts +0 -63
  56. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  57. package/core/plugins/__tests__/manager.test.ts +0 -398
  58. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  59. package/core/plugins/__tests__/registry.test.ts +0 -335
  60. package/core/plugins/built-in/index.ts +0 -142
  61. package/core/plugins/built-in/logger/index.ts +0 -180
  62. package/core/plugins/built-in/monitoring/README.md +0 -193
  63. package/core/plugins/built-in/monitoring/index.ts +0 -912
  64. package/core/plugins/built-in/static/index.ts +0 -289
  65. package/core/plugins/built-in/swagger/index.ts +0 -229
  66. package/core/plugins/built-in/vite/index.ts +0 -316
  67. package/core/plugins/config.ts +0 -348
  68. package/core/plugins/discovery.ts +0 -350
  69. package/core/plugins/executor.ts +0 -351
  70. package/core/plugins/index.ts +0 -195
  71. package/core/plugins/manager.ts +0 -583
  72. package/core/plugins/registry.ts +0 -424
  73. package/core/plugins/types.ts +0 -254
  74. package/core/server/framework.ts +0 -123
  75. package/core/server/index.ts +0 -8
  76. package/core/server/plugins/database.ts +0 -182
  77. package/core/server/plugins/logger.ts +0 -47
  78. package/core/server/plugins/swagger.ts +0 -34
  79. package/core/server/standalone.ts +0 -91
  80. package/core/templates/create-project.ts +0 -455
  81. package/core/types/api.ts +0 -169
  82. package/core/types/build.ts +0 -174
  83. package/core/types/config.ts +0 -68
  84. package/core/types/index.ts +0 -127
  85. package/core/types/plugin.ts +0 -94
  86. package/core/utils/__tests__/errors.test.ts +0 -139
  87. package/core/utils/__tests__/helpers.test.ts +0 -297
  88. package/core/utils/__tests__/logger.test.ts +0 -141
  89. package/core/utils/env-runtime-v2.ts +0 -232
  90. package/core/utils/env-runtime.ts +0 -252
  91. package/core/utils/errors/codes.ts +0 -115
  92. package/core/utils/errors/handlers.ts +0 -63
  93. package/core/utils/errors/index.ts +0 -81
  94. package/core/utils/helpers.ts +0 -180
  95. package/core/utils/index.ts +0 -18
  96. package/core/utils/logger/index.ts +0 -161
  97. package/core/utils/logger.ts +0 -106
  98. package/core/utils/monitoring/index.ts +0 -212
  99. package/tsconfig.json +0 -51
  100. 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
- }