create-roadkit
Version:
Beautiful Next.js roadmap website generator with full-screen kanban boards, dark/light mode, and static export
144 lines (127 loc) • 4.03 kB
text/typescript
/**
* Simplified CLI for testing RoadKit functionality
* This version uses basic Node.js functionality without external prompt libraries
*/
import type {
UserChoices,
Template,
Theme,
Logger,
} from '../types/config';
import { createConfigManager } from '../core/config';
import { createProjectScaffoldingEngine } from '../core/scaffolding';
/**
* Simple logger implementation for testing
*/
export class SimpleLogger implements Logger {
info(message: string, data?: unknown): void {
console.log(`[INFO] ${message}`, data ? JSON.stringify(data, null, 2) : '');
}
warn(message: string, data?: unknown): void {
console.warn(`[WARN] ${message}`, data ? JSON.stringify(data, null, 2) : '');
}
error(message: string, error?: Error | unknown): void {
console.error(`[ERROR] ${message}`, error || '');
}
debug(message: string, data?: unknown): void {
console.debug(`[DEBUG] ${message}`, data ? JSON.stringify(data, null, 2) : '');
}
success(message: string, data?: unknown): void {
console.log(`[SUCCESS] ${message}`, data ? JSON.stringify(data, null, 2) : '');
}
}
/**
* Simple CLI options
*/
export interface SimpleCLIOptions {
name: string;
output: string;
template?: Template;
theme?: Theme;
description?: string;
author?: string;
skipInstall?: boolean;
skipGit?: boolean;
verbose?: boolean;
}
/**
* Simple CLI runner for testing
*/
export async function runSimpleCLI(options: SimpleCLIOptions) {
const logger = new SimpleLogger();
const configManager = createConfigManager(logger);
const scaffoldingEngine = createProjectScaffoldingEngine(logger);
logger.info('Starting RoadKit project generation');
// Create user choices from options
const userChoices: UserChoices = {
projectName: options.name,
description: options.description || `A roadmap website for ${options.name}`,
author: {
name: options.author || 'Anonymous',
},
template: options.template || 'basic',
theme: options.theme || 'modern',
outputDirectory: options.output,
features: {
seo: true,
api: true,
testing: true,
deployment: true,
},
customization: {
primaryColor: '#3b82f6',
secondaryColor: '#64748b',
fontFamily: 'inter',
},
technical: {
typescript: true,
eslint: true,
prettier: true,
tailwind: true,
shadcnUi: true,
},
overwrite: true,
gitInit: !options.skipGit,
installDependencies: !options.skipInstall,
};
try {
// Validate configuration
const validation = configManager.validateConfiguration(userChoices);
if (!validation.success) {
logger.error('Configuration validation failed');
validation.errors?.forEach(error => {
logger.error(` ${error.field}: ${error.message}`);
});
return;
}
if (!validation.config) {
logger.error('Failed to generate configuration');
return;
}
// Generate project
const result = await scaffoldingEngine.generateProject(validation.config, {
skipDependencyInstallation: options.skipInstall,
skipGitInit: options.skipGit,
verbose: options.verbose,
});
if (result.success) {
logger.success('Project generated successfully!');
logger.info(`Project path: ${result.projectPath}`);
logger.info(`Duration: ${result.duration}ms`);
logger.info(`Files created: ${result.filesCreated?.length || 0}`);
logger.info(`Files modified: ${result.filesModified?.length || 0}`);
if (result.nextSteps) {
logger.info('Next steps:');
result.nextSteps.forEach(step => logger.info(` ${step}`));
}
} else {
logger.error('Project generation failed');
result.errors?.forEach(error => logger.error(` ${error}`));
if (result.rollbackInfo?.canRollback) {
logger.info('Rollback is available');
}
}
} catch (error) {
logger.error('Unexpected error during project generation', error);
}
}