Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 32 additions & 31 deletions core/cli/command-registry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { CliCommand, CliContext, CliArgument, CliOption, PluginConfigSchema } from "../plugins/types"
import { fluxStackConfig } from "@config"
import { logger } from "@core/utils/logger"
import { buildLogger } from "@core/utils/build-logger"
import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
import { createHash } from "crypto"
import { createPluginUtils } from "../plugins/config"
Expand Down Expand Up @@ -100,34 +101,34 @@ export class CliCommandRegistry {

async execute(commandName: string, args: string[]): Promise<number> {
const command = this.get(commandName)

if (!command) {
console.error(`❌ Unknown command: ${commandName}`)
buildLogger.error(`❌ Unknown command: ${commandName}`)
this.showHelp()
return 1
}

try {
// Parse arguments and options
const { parsedArgs, parsedOptions } = this.parseArgs(command, args)

// Validate required arguments
if (command.arguments) {
for (let i = 0; i < command.arguments.length; i++) {
const arg = command.arguments[i]
if (arg.required && !parsedArgs[i]) {
console.error(`❌ Missing required argument: ${arg.name}`)
buildLogger.error(`❌ Missing required argument: ${arg.name}`)
this.showCommandHelp(command)
return 1
}
}
}

// Validate required options
if (command.options) {
for (const option of command.options) {
if (option.required && !(option.name in parsedOptions)) {
console.error(`❌ Missing required option: --${option.name}`)
buildLogger.error(`❌ Missing required option: --${option.name}`)
this.showCommandHelp(command)
return 1
}
Expand All @@ -137,9 +138,9 @@ export class CliCommandRegistry {
// Execute command
await command.handler(parsedArgs, parsedOptions, this.context)
return 0

} catch (error) {
console.error(`❌ Command failed:`, error instanceof Error ? error.message : String(error))
buildLogger.error('❌ Command failed:', error instanceof Error ? error.message : String(error))
return 1
}
}
Expand Down Expand Up @@ -231,7 +232,7 @@ export class CliCommandRegistry {
}

showHelp(): void {
console.log(`
buildLogger.info(`
⚡ FluxStack Framework CLI

Usage:
Expand All @@ -241,16 +242,16 @@ Usage:
Built-in Commands:`)

const categories = this.getAllByCategory()

for (const [category, commands] of categories) {
console.log(`\n${category}:`)
buildLogger.info(`\n${category}:`)
for (const command of commands) {
const aliases = command.aliases?.length ? ` (${command.aliases.join(', ')})` : ''
console.log(` ${command.name}${aliases.padEnd(20)} ${command.description}`)
buildLogger.info(` ${command.name}${aliases.padEnd(20)} ${command.description}`)
}
}

console.log(`
buildLogger.info(`
Examples:
flux dev # Start development server
flux build --production # Build for production
Expand All @@ -261,13 +262,13 @@ Use "flux help <command>" for more information about a specific command.`)
}

showCommandHelp(command: CliCommand): void {
console.log(`\n${command.description}`)
buildLogger.info(`\n${command.description}`)

if (command.usage) {
console.log(`\nUsage:\n ${command.usage}`)
buildLogger.info(`\nUsage:\n ${command.usage}`)
} else {
let usage = `flux ${command.name}`

if (command.arguments) {
for (const arg of command.arguments) {
if (arg.required) {
Expand All @@ -277,42 +278,42 @@ Use "flux help <command>" for more information about a specific command.`)
}
}
}

if (command.options?.length) {
usage += ` [options]`
}
console.log(`\nUsage:\n ${usage}`)

buildLogger.info(`\nUsage:\n ${usage}`)
}

if (command.arguments?.length) {
console.log(`\nArguments:`)
buildLogger.info(`\nArguments:`)
for (const arg of command.arguments) {
const required = arg.required ? ' (required)' : ''
const defaultValue = arg.default !== undefined ? ` (default: ${arg.default})` : ''
console.log(` ${arg.name.padEnd(15)} ${arg.description}${required}${defaultValue}`)
buildLogger.info(` ${arg.name.padEnd(15)} ${arg.description}${required}${defaultValue}`)
}
}

if (command.options?.length) {
console.log(`\nOptions:`)
buildLogger.info(`\nOptions:`)
for (const option of command.options) {
const short = option.short ? `-${option.short}, ` : ' '
const required = option.required ? ' (required)' : ''
const defaultValue = option.default !== undefined ? ` (default: ${option.default})` : ''
console.log(` ${short}--${option.name.padEnd(15)} ${option.description}${required}${defaultValue}`)
buildLogger.info(` ${short}--${option.name.padEnd(15)} ${option.description}${required}${defaultValue}`)
}
}

if (command.examples?.length) {
console.log(`\nExamples:`)
buildLogger.info(`\nExamples:`)
for (const example of command.examples) {
console.log(` ${example}`)
buildLogger.info(` ${example}`)
}
}

if (command.aliases?.length) {
console.log(`\nAliases: ${command.aliases.join(', ')}`)
buildLogger.info(`\nAliases: ${command.aliases.join(', ')}`)
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions core/cli/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import type { CLICommand } from '../command-registry'
import { ProjectCreator } from '@core/templates/create-project'
import { buildLogger } from '@core/utils/build-logger'

export const createCommand: CLICommand = {
name: 'create',
Expand Down Expand Up @@ -36,7 +37,7 @@ export const createCommand: CLICommand = {
const template = args[1] as string | undefined

if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
console.error("❌ Project name can only contain letters, numbers, hyphens, and underscores")
buildLogger.error("❌ Project name can only contain letters, numbers, hyphens, and underscores")
return
}

Expand All @@ -48,7 +49,7 @@ export const createCommand: CLICommand = {

await creator.create()
} catch (error) {
console.error("❌ Failed to create project:", error instanceof Error ? error.message : String(error))
buildLogger.error("❌ Failed to create project:", error instanceof Error ? error.message : String(error))
throw error
}
}
Expand Down
7 changes: 4 additions & 3 deletions core/cli/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import type { CLICommand } from '../command-registry'
import { serverConfig, clientConfig } from '@config'
import { buildLogger } from '@core/utils/build-logger'

export const devCommand: CLICommand = {
name: 'dev',
Expand Down Expand Up @@ -53,7 +54,7 @@ export const devCommand: CLICommand = {
const backendOnly = options['backend-only'] === true

if (frontendOnly && backendOnly) {
console.error('❌ Cannot use --frontend-only and --backend-only together')
buildLogger.error('❌ Cannot use --frontend-only and --backend-only together')
process.exit(1)
}

Expand All @@ -67,7 +68,7 @@ export const devCommand: CLICommand = {

const fluxstackMode = backendOnly ? 'backend-only' : 'full-stack'

console.log(`⚡ Starting ${mode} development server...`)
buildLogger.info(`⚡ Starting ${mode} development server...`)

const devProcess = spawn("bun", ["--watch", entryPoint], {
stdio: "inherit",
Expand All @@ -81,7 +82,7 @@ export const devCommand: CLICommand = {
})

process.on('SIGINT', () => {
console.log('\n🛑 Shutting down gracefully...')
buildLogger.info('\n🛑 Shutting down gracefully...')
devProcess.kill('SIGTERM')
setTimeout(() => {
devProcess.kill('SIGKILL')
Expand Down
3 changes: 2 additions & 1 deletion core/cli/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import type { CLICommand } from '../command-registry'
import { cliRegistry } from '../command-registry'
import { buildLogger } from '@core/utils/build-logger'

export const helpCommand: CLICommand = {
name: 'help',
Expand All @@ -24,7 +25,7 @@ export const helpCommand: CLICommand = {
if (targetCommand) {
cliRegistry.showCommandHelp(targetCommand)
} else {
console.error(`❌ Unknown command: ${args[0]}`)
buildLogger.error(`❌ Unknown command: ${args[0]}`)
cliRegistry.showHelp()
}
} else {
Expand Down
7 changes: 4 additions & 3 deletions core/cli/commands/make-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import type { CLICommand } from '../command-registry'
import { buildLogger } from '@core/utils/build-logger'

export const makePluginCommand: CLICommand = {
name: 'make:plugin',
Expand Down Expand Up @@ -52,7 +53,7 @@ export const makePluginCommand: CLICommand = {
const name = args[0] as string

if (!/^[a-zA-Z0-9-_]+$/.test(name)) {
console.error("❌ Plugin name can only contain letters, numbers, hyphens, and underscores")
buildLogger.error("❌ Plugin name can only contain letters, numbers, hyphens, and underscores")
return
}

Expand All @@ -61,7 +62,7 @@ export const makePluginCommand: CLICommand = {
const pluginGenerator = generatorRegistry.get('plugin')

if (!pluginGenerator) {
console.error("❌ Plugin generator not found")
buildLogger.error("❌ Plugin generator not found")
return
}

Expand All @@ -83,7 +84,7 @@ export const makePluginCommand: CLICommand = {
try {
await pluginGenerator.generate(generatorContext, generatorOptions)
} catch (error) {
console.error("❌ Failed to create plugin:", error instanceof Error ? error.message : String(error))
buildLogger.error("❌ Failed to create plugin:", error instanceof Error ? error.message : String(error))
throw error
}
}
Expand Down
Loading
Loading