diff --git a/core/cli/command-registry.ts b/core/cli/command-registry.ts index ed54ca8..0940396 100644 --- a/core/cli/command-registry.ts +++ b/core/cli/command-registry.ts @@ -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" @@ -100,9 +101,9 @@ export class CliCommandRegistry { async execute(commandName: string, args: string[]): Promise { const command = this.get(commandName) - + if (!command) { - console.error(`❌ Unknown command: ${commandName}`) + buildLogger.error(`❌ Unknown command: ${commandName}`) this.showHelp() return 1 } @@ -110,24 +111,24 @@ export class CliCommandRegistry { 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 } @@ -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 } } @@ -231,7 +232,7 @@ export class CliCommandRegistry { } showHelp(): void { - console.log(` + buildLogger.info(` ⚡ FluxStack Framework CLI Usage: @@ -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 @@ -261,13 +262,13 @@ Use "flux help " 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) { @@ -277,42 +278,42 @@ Use "flux help " 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(', ')}`) } } } diff --git a/core/cli/commands/create.ts b/core/cli/commands/create.ts index da6703b..87e3e4d 100644 --- a/core/cli/commands/create.ts +++ b/core/cli/commands/create.ts @@ -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', @@ -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 } @@ -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 } } diff --git a/core/cli/commands/dev.ts b/core/cli/commands/dev.ts index 4e3e8f5..a04aaba 100644 --- a/core/cli/commands/dev.ts +++ b/core/cli/commands/dev.ts @@ -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', @@ -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) } @@ -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", @@ -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') diff --git a/core/cli/commands/help.ts b/core/cli/commands/help.ts index fb9cdcc..56882b3 100644 --- a/core/cli/commands/help.ts +++ b/core/cli/commands/help.ts @@ -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', @@ -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 { diff --git a/core/cli/commands/make-plugin.ts b/core/cli/commands/make-plugin.ts index 9995ee7..6ed67d5 100644 --- a/core/cli/commands/make-plugin.ts +++ b/core/cli/commands/make-plugin.ts @@ -4,6 +4,7 @@ */ import type { CLICommand } from '../command-registry' +import { buildLogger } from '@core/utils/build-logger' export const makePluginCommand: CLICommand = { name: 'make:plugin', @@ -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 } @@ -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 } @@ -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 } } diff --git a/core/cli/commands/plugin-add.ts b/core/cli/commands/plugin-add.ts index 85b11c0..f0812ce 100644 --- a/core/cli/commands/plugin-add.ts +++ b/core/cli/commands/plugin-add.ts @@ -7,7 +7,7 @@ import { Command } from 'commander' import { readFileSync, writeFileSync, existsSync } from 'fs' import { join } from 'path' import { $ } from 'bun' -import chalk from 'chalk' +import { buildLogger } from '@core/utils/build-logger' interface PluginAddOptions { skipAudit?: boolean @@ -21,26 +21,29 @@ export function createPluginAddCommand(): Command { .option('--skip-audit', 'Skip npm audit check') .option('--skip-confirmation', 'Skip confirmation prompt') .action(async (pluginName: string, options: PluginAddOptions) => { - console.log(chalk.blue('\n🔌 FluxStack Plugin Installer\n')) + buildLogger.info('') + buildLogger.info('🔌 FluxStack Plugin Installer') + buildLogger.info('') try { // 1. Validate plugin name if (!isValidPluginName(pluginName)) { - console.error(chalk.red(`❌ Invalid plugin name: ${pluginName}`)) - console.log(chalk.yellow('\n📝 Valid plugin names:')) - console.log(' - fluxstack-plugin-*') - console.log(' - fplugin-*') - console.log(' - @fluxstack/plugin-*') - console.log(' - @fplugin/*') - console.log(' - @org/fluxstack-plugin-*') - console.log(' - @org/fplugin-*') + buildLogger.error(`❌ Invalid plugin name: ${pluginName}`) + buildLogger.info('') + buildLogger.info('📝 Valid plugin names:') + buildLogger.info(' - fluxstack-plugin-*') + buildLogger.info(' - fplugin-*') + buildLogger.info(' - @fluxstack/plugin-*') + buildLogger.info(' - @fplugin/*') + buildLogger.info(' - @org/fluxstack-plugin-*') + buildLogger.info(' - @org/fplugin-*') process.exit(1) } // 2. Check if plugin already installed const packageJsonPath = join(process.cwd(), 'package.json') if (!existsSync(packageJsonPath)) { - console.error(chalk.red('❌ package.json not found')) + buildLogger.error('❌ package.json not found') process.exit(1) } @@ -50,69 +53,83 @@ export function createPluginAddCommand(): Command { packageJson.devDependencies?.[pluginName] if (isAlreadyInstalled && !options.skipConfirmation) { - console.log(chalk.yellow(`⚠️ Plugin ${pluginName} is already installed`)) - console.log(chalk.yellow(' Will only update whitelist\n')) + buildLogger.warn(`⚠️ Plugin ${pluginName} is already installed`) + buildLogger.warn(' Will only update whitelist') + buildLogger.info('') } // 3. Audit plugin (unless skipped) if (!options.skipAudit && !isAlreadyInstalled) { - console.log(chalk.blue('🔍 Auditing plugin security...\n')) + buildLogger.info('🔍 Auditing plugin security...') + buildLogger.info('') try { // Get plugin info const info = await $`npm view ${pluginName} repository homepage version description`.text() - console.log(chalk.gray(info)) + buildLogger.info(info) // Run audit - console.log(chalk.blue('\n🛡️ Running npm audit...\n')) + buildLogger.info('') + buildLogger.info('🛡️ Running npm audit...') + buildLogger.info('') const auditResult = await $`npm audit ${pluginName}`.text() - console.log(chalk.gray(auditResult)) + buildLogger.info(auditResult) } catch (error) { - console.warn(chalk.yellow(`⚠️ Could not audit plugin: ${error instanceof Error ? error.message : 'Unknown error'}`)) + buildLogger.warn(`⚠️ Could not audit plugin: ${error instanceof Error ? error.message : 'Unknown error'}`) } } // 4. Confirmation prompt (unless skipped) if (!options.skipConfirmation) { - console.log(chalk.yellow('\n⚠️ Security Warning:')) - console.log(chalk.yellow(' NPM plugins can execute arbitrary code')) - console.log(chalk.yellow(' Only install plugins from trusted sources\n')) + buildLogger.warn('') + buildLogger.warn('⚠️ Security Warning:') + buildLogger.warn(' NPM plugins can execute arbitrary code') + buildLogger.warn(' Only install plugins from trusted sources') + buildLogger.info('') - const answer = prompt(chalk.blue('Continue with installation? (yes/no): ')) + const answer = prompt('Continue with installation? (yes/no): ') if (answer?.toLowerCase() !== 'yes' && answer?.toLowerCase() !== 'y') { - console.log(chalk.red('❌ Installation cancelled')) + buildLogger.error('❌ Installation cancelled') process.exit(0) } } // 5. Install plugin if (!isAlreadyInstalled) { - console.log(chalk.blue(`\n📦 Installing ${pluginName}...\n`)) + buildLogger.info('') + buildLogger.info(`📦 Installing ${pluginName}...`) + buildLogger.info('') await $`bun add ${pluginName}`.quiet() - console.log(chalk.green(`✅ Plugin installed successfully`)) + buildLogger.success('✅ Plugin installed successfully') } // 6. Update .env file - console.log(chalk.blue('\n🔧 Updating configuration...\n')) + buildLogger.info('') + buildLogger.info('🔧 Updating configuration...') + buildLogger.info('') updateEnvFile(pluginName) // 7. Success message - console.log(chalk.green('\n✅ Plugin setup complete!\n')) - console.log(chalk.blue('📋 What was done:')) + buildLogger.success('') + buildLogger.success('✅ Plugin setup complete!') + buildLogger.info('') + buildLogger.info('📋 What was done:') if (!isAlreadyInstalled) { - console.log(chalk.gray(` • Installed ${pluginName}`)) + buildLogger.info(` • Installed ${pluginName}`) } - console.log(chalk.gray(' • Enabled NPM plugin discovery (PLUGINS_DISCOVER_NPM=true)')) - console.log(chalk.gray(` • Added ${pluginName} to whitelist (PLUGINS_ALLOWED)`)) + buildLogger.info(' • Enabled NPM plugin discovery (PLUGINS_DISCOVER_NPM=true)') + buildLogger.info(` • Added ${pluginName} to whitelist (PLUGINS_ALLOWED)`) - console.log(chalk.blue('\n🚀 Next steps:')) - console.log(chalk.gray(' 1. Restart your dev server: bun run dev')) - console.log(chalk.gray(' 2. Plugin will be auto-discovered and loaded')) - console.log(chalk.gray(' 3. Check logs for plugin initialization')) + buildLogger.info('') + buildLogger.info('🚀 Next steps:') + buildLogger.info(' 1. Restart your dev server: bun run dev') + buildLogger.info(' 2. Plugin will be auto-discovered and loaded') + buildLogger.info(' 3. Check logs for plugin initialization') } catch (error) { - console.error(chalk.red('\n❌ Failed to install plugin:')) - console.error(chalk.red(error instanceof Error ? error.message : String(error))) + buildLogger.error('') + buildLogger.error('❌ Failed to install plugin:') + buildLogger.error(error instanceof Error ? error.message : String(error)) process.exit(1) } }) @@ -143,7 +160,7 @@ function updateEnvFile(pluginName: string): void { const envPath = join(process.cwd(), '.env') if (!existsSync(envPath)) { - console.warn(chalk.yellow('⚠️ .env file not found, creating...')) + buildLogger.warn('⚠️ .env file not found, creating...') writeFileSync(envPath, '', 'utf-8') } @@ -157,11 +174,11 @@ function updateEnvFile(pluginName: string): void { 'PLUGINS_DISCOVER_NPM=true' ) updated = true - console.log(chalk.gray(' • Set PLUGINS_DISCOVER_NPM=true')) + buildLogger.info(' • Set PLUGINS_DISCOVER_NPM=true') } else if (!/^PLUGINS_DISCOVER_NPM=/m.test(envContent)) { envContent += '\n# Plugin Discovery\nPLUGINS_DISCOVER_NPM=true\n' updated = true - console.log(chalk.gray(' • Added PLUGINS_DISCOVER_NPM=true')) + buildLogger.info(' • Added PLUGINS_DISCOVER_NPM=true') } // 2. Add plugin to whitelist @@ -181,14 +198,14 @@ function updateEnvFile(pluginName: string): void { `PLUGINS_ALLOWED=${newPlugins}` ) updated = true - console.log(chalk.gray(` • Added ${pluginName} to PLUGINS_ALLOWED`)) + buildLogger.info(` • Added ${pluginName} to PLUGINS_ALLOWED`) } else { - console.log(chalk.gray(` • ${pluginName} already in PLUGINS_ALLOWED`)) + buildLogger.info(` • ${pluginName} already in PLUGINS_ALLOWED`) } } else { envContent += `PLUGINS_ALLOWED=${pluginName}\n` updated = true - console.log(chalk.gray(` • Created PLUGINS_ALLOWED with ${pluginName}`)) + buildLogger.info(` • Created PLUGINS_ALLOWED with ${pluginName}`) } if (updated) { diff --git a/core/cli/commands/plugin-deps.ts b/core/cli/commands/plugin-deps.ts index 0c95bd6..b3f05e8 100644 --- a/core/cli/commands/plugin-deps.ts +++ b/core/cli/commands/plugin-deps.ts @@ -3,7 +3,7 @@ */ import { Command } from 'commander' -import chalk from 'chalk' +import { buildLogger } from '@core/utils/build-logger' import { PluginDependencyManager } from '@core/plugins/dependency-manager' import { PluginRegistry } from '@core/plugins/registry' import { existsSync, readFileSync } from 'fs' @@ -26,7 +26,8 @@ function createInstallCommand(): Command { .option('--dry-run', 'Mostrar o que seria instalado sem executar') .option('--package-manager ', 'Package manager a usar (npm, yarn, pnpm, bun)', 'bun') .action(async (options) => { - console.log(chalk.blue('🔧 Instalando dependências de plugins...\n')) + buildLogger.info('🔧 Instalando dependências de plugins...') + buildLogger.info('') try { const dependencyManager = new PluginDependencyManager({ @@ -45,7 +46,8 @@ function createInstallCommand(): Command { }) const successfulPlugins = results.filter(r => r.success) - console.log(chalk.green(`✅ Encontrados ${successfulPlugins.length} plugins\n`)) + buildLogger.success(`✅ Encontrados ${successfulPlugins.length} plugins`) + buildLogger.info('') // Resolver dependências const resolutions = [] @@ -62,34 +64,34 @@ function createInstallCommand(): Command { // Mostrar resumo let totalDeps = 0 let totalConflicts = 0 - + for (const resolution of resolutions) { totalDeps += resolution.dependencies.length totalConflicts += resolution.conflicts.length - + if (resolution.dependencies.length > 0) { - console.log(chalk.cyan(`📦 ${resolution.plugin}:`)) + buildLogger.info(`📦 ${resolution.plugin}:`) for (const dep of resolution.dependencies) { - const typeColor = dep.type === 'peerDependency' ? chalk.yellow : chalk.white - console.log(` ${typeColor(dep.name)}@${dep.version} (${dep.type})`) + buildLogger.info(` ${dep.name}@${dep.version} (${dep.type})`) } - console.log() + buildLogger.info('') } } if (totalConflicts > 0) { - console.log(chalk.yellow(`⚠️ ${totalConflicts} conflitos de dependências detectados\n`)) + buildLogger.warn(`⚠️ ${totalConflicts} conflitos de dependências detectados`) + buildLogger.info('') } if (options.dryRun) { - console.log(chalk.blue(`📋 Dry run: ${totalDeps} dependências seriam instaladas`)) + buildLogger.info(`📋 Dry run: ${totalDeps} dependências seriam instaladas`) } else { await dependencyManager.installPluginDependencies(resolutions) - console.log(chalk.green(`✅ ${totalDeps} dependências instaladas com sucesso!`)) + buildLogger.success(`✅ ${totalDeps} dependências instaladas com sucesso!`) } } catch (error) { - console.error(chalk.red('❌ Erro ao instalar dependências:'), error) + buildLogger.error('❌ Erro ao instalar dependências:', error) process.exit(1) } }) @@ -100,7 +102,8 @@ function createListCommand(): Command { .description('Listar dependências de plugins') .option('--plugin ', 'Mostrar apenas dependências de um plugin específico') .action(async (options) => { - console.log(chalk.blue('📋 Dependências de plugins:\n')) + buildLogger.info('📋 Dependências de plugins:') + buildLogger.info('') try { const registry = new PluginRegistry({ @@ -125,30 +128,29 @@ function createListCommand(): Command { const pluginDir = findPluginDirectory(result.plugin.name) if (pluginDir) { const resolution = await dependencyManager.resolvePluginDependencies(pluginDir) - - console.log(chalk.cyan(`📦 ${resolution.plugin}`)) - + + buildLogger.info(`📦 ${resolution.plugin}`) + if (resolution.dependencies.length === 0) { - console.log(chalk.gray(' Nenhuma dependência')) + buildLogger.info(' Nenhuma dependência') } else { for (const dep of resolution.dependencies) { - const typeColor = dep.type === 'peerDependency' ? chalk.yellow : chalk.white - const optional = dep.optional ? chalk.gray(' (opcional)') : '' - console.log(` ${typeColor(dep.name)}@${dep.version} (${dep.type})${optional}`) + const optional = dep.optional ? ' (opcional)' : '' + buildLogger.info(` ${dep.name}@${dep.version} (${dep.type})${optional}`) } } if (resolution.conflicts.length > 0) { - console.log(chalk.red(` ⚠️ ${resolution.conflicts.length} conflitos`)) + buildLogger.error(` ⚠️ ${resolution.conflicts.length} conflitos`) } - console.log() + buildLogger.info('') } } } } catch (error) { - console.error(chalk.red('❌ Erro ao listar dependências:'), error) + buildLogger.error('❌ Erro ao listar dependências:', error) process.exit(1) } }) @@ -158,7 +160,8 @@ function createCheckCommand(): Command { return new Command('check') .description('Verificar conflitos de dependências') .action(async () => { - console.log(chalk.blue('🔍 Verificando conflitos de dependências...\n')) + buildLogger.info('🔍 Verificando conflitos de dependências...') + buildLogger.info('') try { const registry = new PluginRegistry({ @@ -186,26 +189,27 @@ function createCheckCommand(): Command { } const allConflicts = resolutions.flatMap(r => r.conflicts) - + if (allConflicts.length === 0) { - console.log(chalk.green('✅ Nenhum conflito de dependências encontrado!')) + buildLogger.success('✅ Nenhum conflito de dependências encontrado!') } else { - console.log(chalk.red(`❌ ${allConflicts.length} conflitos encontrados:\n`)) - + buildLogger.error(`❌ ${allConflicts.length} conflitos encontrados:`) + buildLogger.info('') + for (const conflict of allConflicts) { - console.log(chalk.yellow(`⚠️ ${conflict.package}:`)) + buildLogger.warn(`⚠️ ${conflict.package}:`) for (const version of conflict.versions) { - console.log(` ${version.plugin}: ${version.version}`) + buildLogger.info(` ${version.plugin}: ${version.version}`) } if (conflict.resolution) { - console.log(chalk.green(` Resolução: ${conflict.resolution}`)) + buildLogger.success(` Resolução: ${conflict.resolution}`) } - console.log() + buildLogger.info('') } } } catch (error) { - console.error(chalk.red('❌ Erro ao verificar conflitos:'), error) + buildLogger.error('❌ Erro ao verificar conflitos:', error) process.exit(1) } }) @@ -216,14 +220,15 @@ function createCleanCommand(): Command { .description('Limpar dependências não utilizadas') .option('--dry-run', 'Mostrar o que seria removido sem executar') .action(async (options) => { - console.log(chalk.blue('🧹 Limpando dependências não utilizadas...\n')) + buildLogger.info('🧹 Limpando dependências não utilizadas...') + buildLogger.info('') if (options.dryRun) { - console.log(chalk.blue('📋 Dry run: mostrando dependências que seriam removidas')) + buildLogger.info('📋 Dry run: mostrando dependências que seriam removidas') } // TODO: Implementar lógica de limpeza - console.log(chalk.yellow('⚠️ Funcionalidade ainda não implementada')) + buildLogger.warn('⚠️ Funcionalidade ainda não implementada') }) } @@ -259,17 +264,17 @@ function createConsoleLogger(): ConsoleLogger { const logger: ConsoleLogger = { debug: (message: unknown, ...args: unknown[]) => { if (process.env.DEBUG) { - console.log(chalk.gray(`[DEBUG] ${message}`), ...args) + buildLogger.info(`[DEBUG] ${message}`, ...args) } }, info: (message: unknown, ...args: unknown[]) => { - console.log(chalk.blue(`[INFO] ${message}`), ...args) + buildLogger.info(`[INFO] ${message}`, ...args) }, warn: (message: unknown, ...args: unknown[]) => { - console.log(chalk.yellow(`[WARN] ${message}`), ...args) + buildLogger.warn(`[WARN] ${message}`, ...args) }, error: (message: unknown, ...args: unknown[]) => { - console.log(chalk.red(`[ERROR] ${message}`), ...args) + buildLogger.error(`[ERROR] ${message}`, ...args) }, child: () => createConsoleLogger(), request: () => {}, diff --git a/core/cli/commands/plugin-list.ts b/core/cli/commands/plugin-list.ts index 0b525e5..9fd3733 100644 --- a/core/cli/commands/plugin-list.ts +++ b/core/cli/commands/plugin-list.ts @@ -6,7 +6,7 @@ import { Command } from 'commander' import { readFileSync, existsSync } from 'fs' import { join } from 'path' -import chalk from 'chalk' +import { buildLogger } from '@core/utils/build-logger' export function createPluginListCommand(): Command { const command = new Command('plugin:list') @@ -19,97 +19,100 @@ export function createPluginListCommand(): Command { const info = getPluginInfo() if (options.json) { - console.log(JSON.stringify(info, null, 2)) + buildLogger.info(JSON.stringify(info, null, 2)) return } - console.log(chalk.blue('\n🔌 FluxStack Plugin Status\n')) + buildLogger.info('') + buildLogger.info('🔌 FluxStack Plugin Status') + buildLogger.info('') // Configuration - console.log(chalk.bold('⚙️ Configuration:')) - console.log(chalk.gray(` NPM Plugin Discovery: ${info.config.npmDiscoveryEnabled ? chalk.green('enabled') : chalk.red('disabled')}`)) - console.log(chalk.gray(` Project Plugin Discovery: ${info.config.projectDiscoveryEnabled ? chalk.green('enabled') : chalk.red('disabled')}`)) - console.log() + buildLogger.info('⚙️ Configuration:') + buildLogger.info(` NPM Plugin Discovery: ${info.config.npmDiscoveryEnabled ? 'enabled' : 'disabled'}`) + buildLogger.info(` Project Plugin Discovery: ${info.config.projectDiscoveryEnabled ? 'enabled' : 'disabled'}`) + buildLogger.info('') // Whitelisted plugins if (!options.installed) { - console.log(chalk.bold('🛡️ Whitelisted NPM Plugins:')) + buildLogger.info('🛡️ Whitelisted NPM Plugins:') if (info.whitelisted.length === 0) { - console.log(chalk.gray(' (none)')) + buildLogger.info(' (none)') } else { info.whitelisted.forEach(plugin => { const isInstalled = info.installed.includes(plugin) - const status = isInstalled ? chalk.green('✓ installed') : chalk.yellow('⚠ not installed') - console.log(chalk.gray(` • ${plugin} ${status}`)) + const status = isInstalled ? '✓ installed' : '⚠ not installed' + buildLogger.info(` • ${plugin} ${status}`) }) } - console.log() + buildLogger.info('') } // Installed NPM plugins if (!options.whitelisted) { - console.log(chalk.bold('📦 Installed NPM Plugins:')) + buildLogger.info('📦 Installed NPM Plugins:') if (info.installed.length === 0) { - console.log(chalk.gray(' (none)')) + buildLogger.info(' (none)') } else { info.installed.forEach(plugin => { const isWhitelisted = info.whitelisted.includes(plugin) let status = '' if (!info.config.npmDiscoveryEnabled) { - status = chalk.red('✗ discovery disabled') + status = '✗ discovery disabled' } else if (!isWhitelisted) { - status = chalk.red('✗ not whitelisted (blocked)') + status = '✗ not whitelisted (blocked)' } else { - status = chalk.green('✓ whitelisted (loaded)') + status = '✓ whitelisted (loaded)' } - console.log(chalk.gray(` • ${plugin} ${status}`)) + buildLogger.info(` • ${plugin} ${status}`) }) } - console.log() + buildLogger.info('') } // Project plugins (from plugins/ directory) - console.log(chalk.bold('📁 Project Plugins (plugins/):')) + buildLogger.info('📁 Project Plugins (plugins/):') if (info.projectPlugins.length === 0) { - console.log(chalk.gray(' (none found)')) + buildLogger.info(' (none found)') } else { info.projectPlugins.forEach(plugin => { const status = info.config.projectDiscoveryEnabled - ? chalk.green('✓ auto-discovered') - : chalk.red('✗ discovery disabled') - console.log(chalk.gray(` • ${plugin} ${status}`)) + ? '✓ auto-discovered' + : '✗ discovery disabled' + buildLogger.info(` • ${plugin} ${status}`) }) } - console.log() + buildLogger.info('') // Summary - console.log(chalk.bold('📊 Summary:')) - console.log(chalk.gray(` Total NPM plugins installed: ${info.installed.length}`)) - console.log(chalk.gray(` Total NPM plugins whitelisted: ${info.whitelisted.length}`)) - console.log(chalk.gray(` Total project plugins: ${info.projectPlugins.length}`)) + buildLogger.info('📊 Summary:') + buildLogger.info(` Total NPM plugins installed: ${info.installed.length}`) + buildLogger.info(` Total NPM plugins whitelisted: ${info.whitelisted.length}`) + buildLogger.info(` Total project plugins: ${info.projectPlugins.length}`) const blockedCount = info.installed.filter(p => !info.whitelisted.includes(p)).length if (blockedCount > 0) { - console.log(chalk.yellow(` ⚠️ ${blockedCount} installed plugin(s) blocked (not whitelisted)`)) + buildLogger.warn(` ⚠️ ${blockedCount} installed plugin(s) blocked (not whitelisted)`) } - console.log() + buildLogger.info('') // Help if (info.installed.length > 0 && !info.config.npmDiscoveryEnabled) { - console.log(chalk.yellow('💡 Tip: Enable NPM plugin discovery with:')) - console.log(chalk.gray(' echo "PLUGINS_DISCOVER_NPM=true" >> .env')) - console.log() + buildLogger.warn('💡 Tip: Enable NPM plugin discovery with:') + buildLogger.info(' echo "PLUGINS_DISCOVER_NPM=true" >> .env') + buildLogger.info('') } if (blockedCount > 0 && info.config.npmDiscoveryEnabled) { - console.log(chalk.yellow('💡 Tip: Add blocked plugins to whitelist with:')) - console.log(chalk.gray(' bun run fluxstack plugin:add ')) - console.log() + buildLogger.warn('💡 Tip: Add blocked plugins to whitelist with:') + buildLogger.info(' bun run fluxstack plugin:add ') + buildLogger.info('') } } catch (error) { - console.error(chalk.red('\n❌ Failed to list plugins:')) - console.error(chalk.red(error instanceof Error ? error.message : String(error))) + buildLogger.error('') + buildLogger.error('❌ Failed to list plugins:') + buildLogger.error(error instanceof Error ? error.message : String(error)) process.exit(1) } }) diff --git a/core/cli/commands/plugin-remove.ts b/core/cli/commands/plugin-remove.ts index 3cd3f4d..1512be6 100644 --- a/core/cli/commands/plugin-remove.ts +++ b/core/cli/commands/plugin-remove.ts @@ -7,7 +7,7 @@ import { Command } from 'commander' import { readFileSync, writeFileSync, existsSync } from 'fs' import { join } from 'path' import { $ } from 'bun' -import chalk from 'chalk' +import { buildLogger } from '@core/utils/build-logger' interface PluginRemoveOptions { skipConfirmation?: boolean @@ -21,13 +21,15 @@ export function createPluginRemoveCommand(): Command { .option('--skip-confirmation', 'Skip confirmation prompt') .option('--keep-installed', 'Keep plugin installed, only remove from whitelist') .action(async (pluginName: string, options: PluginRemoveOptions) => { - console.log(chalk.blue('\n🔌 FluxStack Plugin Remover\n')) + buildLogger.info('') + buildLogger.info('🔌 FluxStack Plugin Remover') + buildLogger.info('') try { // 1. Check if plugin is installed const packageJsonPath = join(process.cwd(), 'package.json') if (!existsSync(packageJsonPath)) { - console.error(chalk.red('❌ package.json not found')) + buildLogger.error('❌ package.json not found') process.exit(1) } @@ -37,8 +39,9 @@ export function createPluginRemoveCommand(): Command { packageJson.devDependencies?.[pluginName] if (!isInstalled && !options.keepInstalled) { - console.log(chalk.yellow(`⚠️ Plugin ${pluginName} is not installed`)) - console.log(chalk.yellow(' Will only remove from whitelist\n')) + buildLogger.warn(`⚠️ Plugin ${pluginName} is not installed`) + buildLogger.warn(' Will only remove from whitelist') + buildLogger.info('') } // 2. Confirmation prompt (unless skipped) @@ -47,48 +50,56 @@ export function createPluginRemoveCommand(): Command { ? 'remove from whitelist' : 'uninstall and remove from whitelist' - const answer = prompt(chalk.yellow(`Remove ${pluginName}? This will ${action}. (yes/no): `)) + const answer = prompt(`Remove ${pluginName}? This will ${action}. (yes/no): `) if (answer?.toLowerCase() !== 'yes' && answer?.toLowerCase() !== 'y') { - console.log(chalk.red('❌ Removal cancelled')) + buildLogger.error('❌ Removal cancelled') process.exit(0) } } // 3. Remove from whitelist - console.log(chalk.blue('\n🔧 Updating configuration...\n')) + buildLogger.info('') + buildLogger.info('🔧 Updating configuration...') + buildLogger.info('') const removed = removeFromWhitelist(pluginName) if (!removed) { - console.log(chalk.yellow(`⚠️ Plugin ${pluginName} was not in whitelist`)) + buildLogger.warn(`⚠️ Plugin ${pluginName} was not in whitelist`) } else { - console.log(chalk.gray(` • Removed ${pluginName} from PLUGINS_ALLOWED`)) + buildLogger.info(` • Removed ${pluginName} from PLUGINS_ALLOWED`) } // 4. Uninstall plugin (unless --keep-installed) if (!options.keepInstalled && isInstalled) { - console.log(chalk.blue(`\n📦 Uninstalling ${pluginName}...\n`)) + buildLogger.info('') + buildLogger.info(`📦 Uninstalling ${pluginName}...`) + buildLogger.info('') await $`bun remove ${pluginName}`.quiet() - console.log(chalk.green(`✅ Plugin uninstalled successfully`)) + buildLogger.success('✅ Plugin uninstalled successfully') } // 5. Check if should disable NPM discovery checkAndDisableNpmDiscovery() // 6. Success message - console.log(chalk.green('\n✅ Plugin removal complete!\n')) - console.log(chalk.blue('📋 What was done:')) - console.log(chalk.gray(` • Removed ${pluginName} from whitelist (PLUGINS_ALLOWED)`)) + buildLogger.success('') + buildLogger.success('✅ Plugin removal complete!') + buildLogger.info('') + buildLogger.info('📋 What was done:') + buildLogger.info(` • Removed ${pluginName} from whitelist (PLUGINS_ALLOWED)`) if (!options.keepInstalled && isInstalled) { - console.log(chalk.gray(` • Uninstalled ${pluginName}`)) + buildLogger.info(` • Uninstalled ${pluginName}`) } - console.log(chalk.blue('\n🚀 Next steps:')) - console.log(chalk.gray(' 1. Restart your dev server: bun run dev')) - console.log(chalk.gray(' 2. Plugin will no longer be loaded')) + buildLogger.info('') + buildLogger.info('🚀 Next steps:') + buildLogger.info(' 1. Restart your dev server: bun run dev') + buildLogger.info(' 2. Plugin will no longer be loaded') } catch (error) { - console.error(chalk.red('\n❌ Failed to remove plugin:')) - console.error(chalk.red(error instanceof Error ? error.message : String(error))) + buildLogger.error('') + buildLogger.error('❌ Failed to remove plugin:') + buildLogger.error(error instanceof Error ? error.message : String(error)) process.exit(1) } }) @@ -164,7 +175,7 @@ function checkAndDisableNpmDiscovery(): void { 'PLUGINS_DISCOVER_NPM=false' ) writeFileSync(envPath, envContent, 'utf-8') - console.log(chalk.gray(' • Disabled NPM plugin discovery (whitelist empty)')) + buildLogger.info(' • Disabled NPM plugin discovery (whitelist empty)') } } } diff --git a/core/cli/generators/component.ts b/core/cli/generators/component.ts index 1ea18aa..53c7905 100644 --- a/core/cli/generators/component.ts +++ b/core/cli/generators/component.ts @@ -1,6 +1,7 @@ import type { Generator } from "./index" import type { GeneratorContext, GeneratorOptions, Template } from "./types" import { templateEngine } from "./template-engine" +import { buildLogger } from "@core/utils/build-logger" export class ComponentGenerator implements Generator { name = 'component' @@ -16,9 +17,9 @@ export class ComponentGenerator implements Generator { const files = await templateEngine.processTemplate(template, context, options) if (options.dryRun) { - console.log(`\n📋 Would generate component '${options.name}':\n`) + buildLogger.info(`\n📋 Would generate component '${options.name}':\n`) for (const file of files) { - console.log(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) + buildLogger.info(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) } return } @@ -30,7 +31,7 @@ export class ComponentGenerator implements Generator { await template.hooks.afterGenerate(context, options, filePaths) } - console.log(`\n✅ Generated component '${options.name}' with ${files.length} files`) + buildLogger.success(`Generated component '${options.name}' with ${files.length} files`) } private getTemplate(templateName?: string): Template { diff --git a/core/cli/generators/controller.ts b/core/cli/generators/controller.ts index 1fbae48..2d20851 100644 --- a/core/cli/generators/controller.ts +++ b/core/cli/generators/controller.ts @@ -1,6 +1,7 @@ import type { Generator } from "./index" import type { GeneratorContext, GeneratorOptions, Template } from "./types" import { templateEngine } from "./template-engine" +import { buildLogger } from "@core/utils/build-logger" export class ControllerGenerator implements Generator { name = 'controller' @@ -17,9 +18,9 @@ export class ControllerGenerator implements Generator { const files = await templateEngine.processTemplate(template, context, options) if (options.dryRun) { - console.log(`\n📋 Would generate controller '${options.name}':\n`) + buildLogger.info(`\n📋 Would generate controller '${options.name}':\n`) for (const file of files) { - console.log(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) + buildLogger.info(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) } return } @@ -32,7 +33,7 @@ export class ControllerGenerator implements Generator { await template.hooks.afterGenerate(context, options, filePaths) } - console.log(`\n✅ Generated controller '${options.name}' with ${files.length} files`) + buildLogger.success(`Generated controller '${options.name}' with ${files.length} files`) } private getTemplate(templateName?: string): Template { diff --git a/core/cli/generators/index.ts b/core/cli/generators/index.ts index a467976..78a3b2b 100644 --- a/core/cli/generators/index.ts +++ b/core/cli/generators/index.ts @@ -5,6 +5,7 @@ import { ComponentGenerator } from "./component" import { ServiceGenerator } from "./service" import { PluginGenerator } from "./plugin" import type { GeneratorContext, GeneratorOptions } from "./types" +import { buildLogger } from "@core/utils/build-logger" export interface Generator { name: string @@ -111,10 +112,10 @@ export const generateCommand: CliCommand = { const generator = generatorRegistry.get(type) if (!generator) { - console.error(`❌ Unknown generator type: ${type}`) - console.log('\nAvailable generators:') + buildLogger.error(`Unknown generator type: ${type}`) + buildLogger.info('\nAvailable generators:') for (const gen of generatorRegistry.getAll()) { - console.log(` ${gen.name.padEnd(12)} ${gen.description}`) + buildLogger.info(` ${gen.name.padEnd(12)} ${gen.description}`) } return } @@ -138,10 +139,10 @@ export const generateCommand: CliCommand = { await generator.generate(generatorContext, generatorOptions) if (!options['dry-run']) { - console.log(`✅ Successfully generated ${type}: ${name}`) + buildLogger.success(`Successfully generated ${type}: ${name}`) } } catch (error) { - console.error(`❌ Failed to generate ${type}:`, error instanceof Error ? error.message : String(error)) + buildLogger.error(`Failed to generate ${type}: ${error instanceof Error ? error.message : String(error)}`) throw error } } diff --git a/core/cli/generators/interactive.ts b/core/cli/generators/interactive.ts index ad561bc..aa90057 100644 --- a/core/cli/generators/interactive.ts +++ b/core/cli/generators/interactive.ts @@ -2,6 +2,7 @@ import type { CliCommand } from "../../plugins/types" import { generatorRegistry } from "./index" import type { GeneratorContext, GeneratorOptions } from "./types" import { promptSystem } from "./prompts" +import { buildLogger } from "@core/utils/build-logger" export const interactiveGenerateCommand: CliCommand = { name: 'generate:interactive', @@ -14,7 +15,7 @@ export const interactiveGenerateCommand: CliCommand = { 'flux gi' ], handler: async (args, options, context) => { - console.log('🎯 FluxStack Interactive Code Generator\n') + buildLogger.info('🎯 FluxStack Interactive Code Generator\n') // Select generator type const generators = generatorRegistry.getAll() @@ -30,7 +31,7 @@ export const interactiveGenerateCommand: CliCommand = { const generator = generatorRegistry.get(selectedType) if (!generator) { - console.error(`❌ Generator not found: ${selectedType}`) + buildLogger.error(`Generator not found: ${selectedType}`) return } @@ -110,7 +111,7 @@ export const interactiveGenerateCommand: CliCommand = { ) // Show dry run first - console.log('\n📋 Preview of files to be generated:\n') + buildLogger.info('\n📋 Preview of files to be generated:\n') const generatorContext: GeneratorContext = { workingDir: context.workingDir, @@ -136,7 +137,7 @@ export const interactiveGenerateCommand: CliCommand = { ) if (!proceed) { - console.log('❌ Generation cancelled') + buildLogger.warn('Generation cancelled') return } @@ -144,13 +145,13 @@ export const interactiveGenerateCommand: CliCommand = { generatorOptions.dryRun = false await generator.generate(generatorContext, generatorOptions) - console.log(`\n✅ Successfully generated ${selectedType}: ${name}`) + buildLogger.success(`Successfully generated ${selectedType}: ${name}`) // Ask if user wants to generate related files await suggestRelatedGenerations(selectedType, name, generatorContext) } catch (error) { - console.error(`❌ Failed to generate ${selectedType}:`, error instanceof Error ? error.message : String(error)) + buildLogger.error(`Failed to generate ${selectedType}: ${error instanceof Error ? error.message : String(error)}`) throw error } } @@ -189,9 +190,9 @@ async function suggestRelatedGenerations( return } - console.log('\n💡 Suggested next steps:') + buildLogger.info('\n💡 Suggested next steps:') for (const suggestion of suggestions) { - console.log(` • ${suggestion.description}`) + buildLogger.info(` • ${suggestion.description}`) } const generateRelated = await promptSystem.confirm( @@ -218,9 +219,9 @@ async function suggestRelatedGenerations( force: false, dryRun: false }) - console.log(`✅ Generated ${suggestion.type}: ${name}`) + buildLogger.success(`Generated ${suggestion.type}: ${name}`) } catch (error) { - console.error(`❌ Failed to generate ${suggestion.type}:`, error instanceof Error ? error.message : String(error)) + buildLogger.error(`Failed to generate ${suggestion.type}: ${error instanceof Error ? error.message : String(error)}`) } } } diff --git a/core/cli/generators/plugin.ts b/core/cli/generators/plugin.ts index 17f37f8..e89d4d7 100644 --- a/core/cli/generators/plugin.ts +++ b/core/cli/generators/plugin.ts @@ -1,6 +1,7 @@ import type { Generator } from "./index" import type { GeneratorContext, GeneratorOptions, Template } from "./types" import { templateEngine } from "./template-engine" +import { buildLogger } from "@core/utils/build-logger" import { join } from "path" export class PluginGenerator implements Generator { @@ -17,9 +18,9 @@ export class PluginGenerator implements Generator { const files = await templateEngine.processTemplate(template, context, options) if (options.dryRun) { - console.log(`\n📋 Would generate plugin '${options.name}':\n`) + buildLogger.info(`\n📋 Would generate plugin '${options.name}':\n`) for (const file of files) { - console.log(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) + buildLogger.info(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) } return } @@ -31,14 +32,14 @@ export class PluginGenerator implements Generator { await template.hooks.afterGenerate(context, options, filePaths) } - console.log(`\n✅ Generated plugin '${options.name}' with ${files.length} files`) - console.log(`\n📦 Next steps:`) - console.log(` 1. Configure plugin in plugins/${options.name}/config/index.ts`) - console.log(` 2. Set environment variables (optional): ${options.name.toUpperCase().replace(/-/g, '_')}_*`) - console.log(` 3. Implement your plugin logic in plugins/${options.name}/index.ts`) - console.log(` 4. Add server-side code in plugins/${options.name}/server/ (optional)`) - console.log(` 5. Add client-side code in plugins/${options.name}/client/ (optional)`) - console.log(` 6. Run: bun run dev`) + buildLogger.success(`Generated plugin '${options.name}' with ${files.length} files`) + buildLogger.info(`\n📦 Next steps:`) + buildLogger.info(` 1. Configure plugin in plugins/${options.name}/config/index.ts`) + buildLogger.info(` 2. Set environment variables (optional): ${options.name.toUpperCase().replace(/-/g, '_')}_*`) + buildLogger.info(` 3. Implement your plugin logic in plugins/${options.name}/index.ts`) + buildLogger.info(` 4. Add server-side code in plugins/${options.name}/server/ (optional)`) + buildLogger.info(` 5. Add client-side code in plugins/${options.name}/client/ (optional)`) + buildLogger.info(` 6. Run: bun run dev`) } private getTemplate(templateName?: string): Template { diff --git a/core/cli/generators/prompts.ts b/core/cli/generators/prompts.ts index f32a509..71f21af 100644 --- a/core/cli/generators/prompts.ts +++ b/core/cli/generators/prompts.ts @@ -1,4 +1,5 @@ import type { PromptConfig } from "./types" +import { buildLogger } from "@core/utils/build-logger" export class PromptSystem { async prompt(config: PromptConfig): Promise { @@ -29,7 +30,7 @@ export class PromptSystem { if (config.validate) { const validation = config.validate(input) if (validation !== true) { - console.log(`Error: ${validation}`) + buildLogger.error(`${validation}`) // In a real implementation, you'd re-prompt resolve(input) return diff --git a/core/cli/generators/route.ts b/core/cli/generators/route.ts index 8c5d73d..94a9ae8 100644 --- a/core/cli/generators/route.ts +++ b/core/cli/generators/route.ts @@ -1,6 +1,7 @@ import type { Generator } from "./index" import type { GeneratorContext, GeneratorOptions, Template } from "./types" import { templateEngine } from "./template-engine" +import { buildLogger } from "@core/utils/build-logger" export class RouteGenerator implements Generator { name = 'route' @@ -16,9 +17,9 @@ export class RouteGenerator implements Generator { const files = await templateEngine.processTemplate(template, context, options) if (options.dryRun) { - console.log(`\n📋 Would generate route '${options.name}':\n`) + buildLogger.info(`\n📋 Would generate route '${options.name}':\n`) for (const file of files) { - console.log(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) + buildLogger.info(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) } return } @@ -30,7 +31,7 @@ export class RouteGenerator implements Generator { await template.hooks.afterGenerate(context, options, filePaths) } - console.log(`\n✅ Generated route '${options.name}' with ${files.length} files`) + buildLogger.success(`Generated route '${options.name}' with ${files.length} files`) } private getTemplate(templateName?: string): Template { diff --git a/core/cli/generators/service.ts b/core/cli/generators/service.ts index 1ee08b0..2f573e5 100644 --- a/core/cli/generators/service.ts +++ b/core/cli/generators/service.ts @@ -1,6 +1,7 @@ import type { Generator } from "./index" import type { GeneratorContext, GeneratorOptions, Template } from "./types" import { templateEngine } from "./template-engine" +import { buildLogger } from "@core/utils/build-logger" export class ServiceGenerator implements Generator { name = 'service' @@ -16,9 +17,9 @@ export class ServiceGenerator implements Generator { const files = await templateEngine.processTemplate(template, context, options) if (options.dryRun) { - console.log(`\n📋 Would generate service '${options.name}':\n`) + buildLogger.info(`\n📋 Would generate service '${options.name}':\n`) for (const file of files) { - console.log(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) + buildLogger.info(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) } return } @@ -30,7 +31,7 @@ export class ServiceGenerator implements Generator { await template.hooks.afterGenerate(context, options, filePaths) } - console.log(`\n✅ Generated service '${options.name}' with ${files.length} files`) + buildLogger.success(`Generated service '${options.name}' with ${files.length} files`) } private getTemplate(templateName?: string): Template { diff --git a/core/cli/generators/template-engine.ts b/core/cli/generators/template-engine.ts index b7c59dc..ad9b10d 100644 --- a/core/cli/generators/template-engine.ts +++ b/core/cli/generators/template-engine.ts @@ -2,6 +2,7 @@ import type { GeneratorContext, GeneratorOptions, Template, TemplateFile, Genera import { join, dirname } from "path" import { mkdir, writeFile, readFile, stat } from "fs/promises" import { existsSync } from "fs" +import { buildLogger } from "@core/utils/build-logger" export class TemplateEngine { private processor: TemplateProcessor @@ -58,7 +59,7 @@ export class TemplateEngine { } if (dryRun) { - console.log(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) + buildLogger.info(`${file.action === 'create' ? '📄' : '✏️'} ${file.path}`) continue } diff --git a/core/cli/index.ts b/core/cli/index.ts index 2035154..007cc84 100644 --- a/core/cli/index.ts +++ b/core/cli/index.ts @@ -8,6 +8,7 @@ import { cliRegistry } from "./command-registry" import { pluginDiscovery } from "./plugin-discovery" import { generateCommand, interactiveGenerateCommand } from "./generators/index" +import { buildLogger } from "@core/utils/build-logger" // Import modular commands import { builtInCommands } from "./commands" @@ -116,7 +117,7 @@ async function registerBuiltInCommands() { category: 'Plugins', handler: async (args, options, context) => { if (args.length === 0) { - console.log(` + buildLogger.info(` ⚡ FluxStack Plugin Dependencies Manager Usage: @@ -165,8 +166,8 @@ Examples: } break default: - console.error(`❌ Unknown subcommand: ${subcommand}`) - console.error('Available subcommands: install, list, check, clean') + buildLogger.error(`❌ Unknown subcommand: ${subcommand}`) + buildLogger.error('Available subcommands: install, list, check, clean') } } }) @@ -187,6 +188,6 @@ async function main() { } main().catch((error) => { - console.error('CLI Error:', error) + buildLogger.error('CLI Error:', error) process.exit(1) }) diff --git a/core/client/standalone.ts b/core/client/standalone.ts index 9c92d65..8dac0e6 100644 --- a/core/client/standalone.ts +++ b/core/client/standalone.ts @@ -5,6 +5,7 @@ import { clientConfig } from '@config' import type { LogLevel } from 'vite' +import { buildLogger } from "../utils/build-logger" type ViteDevServer = Awaited> @@ -15,9 +16,9 @@ export const startFrontendOnly = async (config: Record = {}) => const host = (config.viteHost ?? clientConfig.vite.host ?? 'localhost') as string const logLevel = (config.logLevel || clientConfig.vite.logLevel || 'info') as LogLevel - console.log(`⚛️ FluxStack Frontend Only`) - console.log(`🌐 http://${host}:${port}`) - console.log() + buildLogger.info(`⚛️ FluxStack Frontend Only`) + buildLogger.info(`🌐 http://${host}:${port}`) + buildLogger.info('') try { // Dynamic import of vite @@ -36,13 +37,13 @@ export const startFrontendOnly = async (config: Record = {}) => await viteServer.listen() - console.log(`✅ Frontend server ready!`) - console.log() + buildLogger.success(`✅ Frontend server ready!`) + buildLogger.info('') // Setup cleanup on process exit const cleanup = async () => { if (viteServer) { - console.log('\n🛑 Stopping frontend...') + buildLogger.info('\n🛑 Stopping frontend...') await viteServer.close() viteServer = null process.exit(0) @@ -63,15 +64,15 @@ export const startFrontendOnly = async (config: Record = {}) => (errorMessage.includes('Port') && errorMessage.includes('is in use')) if (isPortInUse) { - console.error(`❌ Failed to start Vite: Port ${port} is already in use`) - console.log(`💡 Try one of these solutions:`) - console.log(` 1. Stop the process using port ${port}`) - console.log(` 2. Change VITE_PORT in your .env file`) - console.log(` 3. Kill the process: ${process.platform === 'win32' ? `netstat -ano | findstr :${port}` : `lsof -ti:${port} | xargs kill -9`}`) + buildLogger.error(`❌ Failed to start Vite: Port ${port} is already in use`) + buildLogger.info(`💡 Try one of these solutions:`) + buildLogger.info(` 1. Stop the process using port ${port}`) + buildLogger.info(` 2. Change VITE_PORT in your .env file`) + buildLogger.info(` 3. Kill the process: ${process.platform === 'win32' ? `netstat -ano | findstr :${port}` : `lsof -ti:${port} | xargs kill -9`}`) process.exit(1) } else { - console.error('❌ Failed to start Vite server:', errorMessage) - console.error('Full error:', error) + buildLogger.error('❌ Failed to start Vite server:', errorMessage) + buildLogger.error('Full error:', error) process.exit(1) } } diff --git a/core/config/index.ts b/core/config/index.ts index 903be96..cbcd275 100644 --- a/core/config/index.ts +++ b/core/config/index.ts @@ -10,6 +10,7 @@ import type { FluxStackConfig } from '@config' import { fluxStackConfig } from '@config' import { helpers } from '../utils/env' +import { logger } from '../utils/logger' // ============================================================================ // 📦 TYPE RE-EXPORTS (for backward compatibility) diff --git a/core/server/plugins/database.ts b/core/server/plugins/database.ts index 0827978..584c093 100644 --- a/core/server/plugins/database.ts +++ b/core/server/plugins/database.ts @@ -1,4 +1,5 @@ import type { FluxStack, PluginContext, CliCommand, Plugin } from "../../plugins/types" +import { logger } from "@core/utils/logger" // Database plugin with CLI commands export const databasePlugin: Plugin = { @@ -42,24 +43,24 @@ export const databasePlugin: Plugin = { ], handler: async (args, options, context) => { if (options["dry-run"]) { - console.log("🔍 Dry run mode - showing planned migrations:") + logger.info("Dry run mode - showing planned migrations:") } if (options.rollback) { - console.log("⬇️ Rolling back last migration...") + logger.info("Rolling back last migration...") // Simulate rollback await new Promise(resolve => setTimeout(resolve, 1000)) - console.log("✅ Rollback completed") + logger.info("Rollback completed") } else if (options.to) { - console.log(`📈 Migrating to version: ${options.to}`) + logger.info(`Migrating to version: ${options.to}`) // Simulate migration to version await new Promise(resolve => setTimeout(resolve, 1500)) - console.log(`✅ Migrated to version ${options.to}`) + logger.info(`Migrated to version ${options.to}`) } else { - console.log("📈 Running all pending migrations...") + logger.info("Running all pending migrations...") // Simulate migration await new Promise(resolve => setTimeout(resolve, 2000)) - console.log("✅ All migrations completed") + logger.info("All migrations completed") } } }, @@ -90,17 +91,17 @@ export const databasePlugin: Plugin = { ], handler: async (args, options, context) => { const [seeder] = args - + if (seeder) { - console.log(`🌱 Running seeder: ${seeder}`) - console.log(` Force mode: ${options.force ? 'ON' : 'OFF'}`) + logger.info(`Running seeder: ${seeder}`) + logger.info(` Force mode: ${options.force ? 'ON' : 'OFF'}`) } else { - console.log("🌱 Running all seeders...") + logger.info("Running all seeders...") } - + // Simulate seeding await new Promise(resolve => setTimeout(resolve, 1500)) - console.log("✅ Database seeded successfully") + logger.info("Database seeded successfully") } }, { @@ -127,23 +128,23 @@ export const databasePlugin: Plugin = { ], handler: async (args, options, context) => { if (!options.confirm) { - console.log("⚠️ WARNING: This will delete all data in the database!") - console.log("Use --confirm to skip this prompt.") + logger.warn("WARNING: This will delete all data in the database!") + logger.info("Use --confirm to skip this prompt.") return } - console.log("🗑️ Dropping all tables...") + logger.info("Dropping all tables...") await new Promise(resolve => setTimeout(resolve, 1000)) - - console.log("📈 Running migrations...") + + logger.info("Running migrations...") await new Promise(resolve => setTimeout(resolve, 1500)) - + if (options.seed) { - console.log("🌱 Running seeders...") + logger.info("Running seeders...") await new Promise(resolve => setTimeout(resolve, 1000)) } - - console.log("✅ Database reset completed") + + logger.info("Database reset completed") } }, { @@ -152,13 +153,13 @@ export const databasePlugin: Plugin = { category: "Database", aliases: ["info"], handler: async (args, options, context) => { - console.log("📊 Database Status:") - console.log("------------------") - console.log("Connected: ✅ Yes") - console.log("Tables: 15") - console.log("Last migration: 2024_01_15_create_users_table") - console.log("Pending migrations: 2") - console.log("Database size: 2.3 MB") + logger.info("Database Status:") + logger.info("------------------") + logger.info("Connected: Yes") + logger.info("Tables: 15") + logger.info("Last migration: 2024_01_15_create_users_table") + logger.info("Pending migrations: 2") + logger.info("Database size: 2.3 MB") } } ] @@ -167,15 +168,15 @@ export const databasePlugin: Plugin = { // Utility functions that could be used by the plugin export async function runMigration(version?: string): Promise { // Actual migration logic would go here - console.log(`Running migration ${version || 'all'}`) + logger.info(`Running migration ${version || 'all'}`) } export async function rollbackMigration(): Promise { - // Actual rollback logic would go here - console.log("Rolling back migration") + // Actual rollback logic would go here + logger.info("Rolling back migration") } export async function seedDatabase(seeder?: string): Promise { // Actual seeding logic would go here - console.log(`Seeding database ${seeder || 'all'}`) + logger.info(`Seeding database ${seeder || 'all'}`) } \ No newline at end of file diff --git a/core/server/rooms/RoomBroadcaster.ts b/core/server/rooms/RoomBroadcaster.ts index 81d4dd8..b43d978 100644 --- a/core/server/rooms/RoomBroadcaster.ts +++ b/core/server/rooms/RoomBroadcaster.ts @@ -2,6 +2,7 @@ import type { ServerWebSocket } from 'bun' import type { Room, RoomSystem, SystemEvents } from './RoomSystem' +import { logger } from "@core/utils/logger" type WebSocketLike = { send: (data: string) => void @@ -238,7 +239,7 @@ export class RoomBroadcaster> { connection.ws.send(JSON.stringify(message)) return true } catch (error) { - console.error(`[RoomBroadcaster] Error sending to ${connectionId}:`, error) + logger.error(`[RoomBroadcaster] Error sending to ${connectionId}:`, error) return false } } diff --git a/core/server/rooms/RoomSystem.ts b/core/server/rooms/RoomSystem.ts index 6bb9d25..9a558b0 100644 --- a/core/server/rooms/RoomSystem.ts +++ b/core/server/rooms/RoomSystem.ts @@ -1,5 +1,7 @@ // 🔥 FluxStack Room System - Pub/Sub tipado para comunicação entre componentes +import { logger } from "@core/utils/logger" + // eslint-disable-next-line @typescript-eslint/no-explicit-any -- default `any` needed for contravariant handler storage type EventHandler = (data: T) => void type Unsubscribe = () => void @@ -178,7 +180,7 @@ export class Room> { sub.handler(data) notified++ } catch (error) { - console.error(`[Room:${this.id}] Error in handler for '${event}':`, error) + logger.error(`[Room:${this.id}] Error in handler for '${event}':`, error) this.emitSystem('$error', { error: error as Error, context: `Handler for event '${event}'` @@ -396,7 +398,7 @@ export class RoomSystem> { try { handler(data) } catch (error) { - console.error(`[RoomSystem:${this.name}] Error in global handler for '${event}':`, error) + logger.error(`[RoomSystem:${this.name}] Error in global handler for '${event}':`, error) } } } diff --git a/core/templates/create-project.ts b/core/templates/create-project.ts index a260cbf..df83e86 100644 --- a/core/templates/create-project.ts +++ b/core/templates/create-project.ts @@ -1,6 +1,7 @@ import { spawn } from "bun" import { join, resolve } from "path" import { mkdir } from "fs/promises" +import { buildLogger } from "@core/utils/build-logger" export interface CreateProjectOptions { name: string @@ -20,9 +21,9 @@ export class ProjectCreator { } async create() { - console.log(`🎉 Creating FluxStack project: ${this.projectName}`) - console.log(`📁 Target directory: ${this.targetDir}`) - console.log() + buildLogger.info(`🎉 Creating FluxStack project: ${this.projectName}`) + buildLogger.info(`📁 Target directory: ${this.targetDir}`) + buildLogger.info('') try { // 1. Create project directory @@ -42,30 +43,30 @@ export class ProjectCreator { // 6. Install dependencies (last step) await this.installDependencies() - - console.log() - console.log("🎉 Project created successfully!") - console.log() - console.log("Next steps:") - console.log(` cd ${this.projectName}`) - console.log(` bun run dev`) - console.log() - console.log("Happy coding! 🚀") - + + buildLogger.info('') + buildLogger.success("🎉 Project created successfully!") + buildLogger.info('') + buildLogger.info("Next steps:") + buildLogger.info(` cd ${this.projectName}`) + buildLogger.info(` bun run dev`) + buildLogger.info('') + buildLogger.info("Happy coding! 🚀") + } catch (error) { - console.error("❌ Error creating project:", error instanceof Error ? error.message : String(error)) + buildLogger.error("❌ Error creating project:", error instanceof Error ? error.message : String(error)) process.exit(1) } } private async createDirectory() { - console.log("📁 Creating project directory...") + buildLogger.info("📁 Creating project directory...") await mkdir(this.targetDir, { recursive: true }) } private async copyTemplate() { - console.log("📋 Copying template files...") - + buildLogger.info("📋 Copying template files...") + // Copy files using Bun's built-in functions for better performance const rootDir = join(__dirname, '..', '..') @@ -106,7 +107,7 @@ export class ProjectCreator { try { entries = await fs.readdir(src, { withFileTypes: true }) } catch (error) { - console.warn(`Warning: Could not read directory ${src}`) + buildLogger.warn(`Warning: Could not read directory ${src}`) return } @@ -126,8 +127,8 @@ export class ProjectCreator { } private async generatePackageJson() { - console.log("📦 Generating package.json...") - + buildLogger.info("📦 Generating package.json...") + const packageJson = { name: this.projectName, version: "1.0.0", @@ -191,7 +192,7 @@ export class ProjectCreator { } private async generateConfigFiles() { - console.log("⚙️ Generating config files...") + buildLogger.info("⚙️ Generating config files...") // TypeScript config const tsConfig = { @@ -552,8 +553,8 @@ Built with ❤️ using FluxStack framework. } private async installDependencies() { - console.log("📦 Installing dependencies...") - + buildLogger.info("📦 Installing dependencies...") + const installProcess = spawn({ cmd: ["bun", "install"], cwd: this.targetDir, @@ -569,8 +570,8 @@ Built with ❤️ using FluxStack framework. } private async initGit() { - console.log("🔧 Initializing git repository...") - + buildLogger.info("🔧 Initializing git repository...") + try { // Initialize git repository await spawn({ @@ -596,7 +597,7 @@ Built with ❤️ using FluxStack framework. stderr: "ignore" }).exited } catch (error) { - console.warn("⚠️ Git initialization failed (git may not be installed)") + buildLogger.warn("⚠️ Git initialization failed (git may not be installed)") } } } \ No newline at end of file diff --git a/core/utils/sync-version.ts b/core/utils/sync-version.ts index 57ceb11..0ec2a7d 100644 --- a/core/utils/sync-version.ts +++ b/core/utils/sync-version.ts @@ -7,6 +7,7 @@ import { readFileSync, writeFileSync } from 'fs' import { join } from 'path' +import { buildLogger } from "./build-logger" interface PackageJson { version: string @@ -37,7 +38,7 @@ export const FLUXSTACK_VERSION = '${version}' ` writeFileSync(versionPath, versionContent) if (!silent) { - console.log(`✅ Updated version.ts to v${version}`) + buildLogger.success(`✅ Updated version.ts to v${version}`) } } @@ -49,11 +50,11 @@ function syncVersion(silent = false): void { const packageVersion = getPackageVersion() updateVersionFile(packageVersion, silent) if (!silent) { - console.log(`🔄 Version synchronized: v${packageVersion}`) + buildLogger.info(`🔄 Version synchronized: v${packageVersion}`) } } catch (error) { if (!silent) { - console.error('❌ Failed to sync version:', error) + buildLogger.error('❌ Failed to sync version:', error) } process.exit(1) }