create-roadkit
Version:
Beautiful Next.js roadmap website generator with full-screen kanban boards, dark/light mode, and static export
246 lines (214 loc) ⢠6.85 kB
text/typescript
#!/usr/bin/env bun
/**
* RoadKit CLI Binary Entry Point
*
* This is the main executable entry point for the RoadKit CLI tool.
* It parses command line arguments and executes the appropriate CLI commands.
*/
import { parseArgs } from 'util';
import { runCLI } from './index';
import type { CLIOptions } from './index';
/**
* Command line argument parsing configuration
* This defines all supported CLI flags and options
*/
const { values: args, positionals } = parseArgs({
args: Bun.argv.slice(2), // Remove 'bun' and script name
allowPositionals: true,
options: {
// Project configuration options
name: {
type: 'string',
short: 'n',
description: 'Project name',
},
template: {
type: 'string',
short: 't',
description: 'Project template (basic, advanced, enterprise, custom)',
},
theme: {
type: 'string',
short: 'T',
description: 'Visual theme (modern, classic, minimal, corporate)',
},
output: {
type: 'string',
short: 'o',
description: 'Output directory path',
},
// Behavior flags
'skip-prompts': {
type: 'boolean',
description: 'Skip interactive prompts',
},
verbose: {
type: 'boolean',
short: 'v',
description: 'Enable verbose logging',
},
'dry-run': {
type: 'boolean',
description: 'Perform a dry run without creating files',
},
overwrite: {
type: 'boolean',
description: 'Overwrite existing directory',
},
'skip-install': {
type: 'boolean',
description: 'Skip dependency installation',
},
'skip-git': {
type: 'boolean',
description: 'Skip git repository initialization',
},
// Help and version
help: {
type: 'boolean',
short: 'h',
description: 'Show help information',
},
version: {
type: 'boolean',
short: 'V',
description: 'Show version information',
},
},
});
/**
* Display help information
*/
function displayHelp(): void {
const helpText = `
š£ļø RoadKit - Next.js Roadmap Website Generator
USAGE:
bun run generate [options]
bun run cli [options]
OPTIONS:
-n, --name <name> Project name
-t, --template <template> Project template (basic, advanced, enterprise, custom)
-T, --theme <theme> Visual theme (modern, classic, minimal, corporate)
-o, --output <path> Output directory path
--skip-prompts Skip interactive prompts
--dry-run Perform a dry run without creating files
--overwrite Overwrite existing directory
--skip-install Skip dependency installation
--skip-git Skip git repository initialization
-v, --verbose Enable verbose logging
-h, --help Show this help message
-V, --version Show version information
EXAMPLES:
# Interactive mode (recommended)
bun run generate
# Quick generation with basic template
bun run generate --name my-roadmap --template basic --theme modern
# Advanced generation with custom options
bun run generate --name my-roadmap --template advanced --theme corporate --output ./my-project
# Dry run to see what would be created
bun run generate --name test --dry-run --verbose
TEMPLATES:
basic - Simple roadmap with essential features
advanced - Feature-rich with analytics and SEO
enterprise - Full-featured with authentication and database
custom - Minimal template for custom builds
THEMES:
modern - Clean, contemporary design
classic - Traditional, professional look
minimal - Simple, focused design
corporate - Business-oriented styling
For more information, visit: https://github.com/your-repo/roadkit
`;
console.log(helpText);
}
/**
* Display version information
*/
function displayVersion(): void {
const packageJson = require('../../package.json');
console.log(`RoadKit v${packageJson.version || '1.0.0'}`);
}
/**
* Validate command line arguments
* @param args - Parsed command line arguments
* @returns Validation result with errors if any
*/
function validateArgs(args: any): { valid: boolean; errors: string[] } {
const errors: string[] = [];
// Validate template if provided
if (args.template) {
const validTemplates = ['basic', 'advanced', 'enterprise', 'custom'];
if (!validTemplates.includes(args.template)) {
errors.push(`Invalid template '${args.template}'. Must be one of: ${validTemplates.join(', ')}`);
}
}
// Validate theme if provided
if (args.theme) {
const validThemes = ['modern', 'classic', 'minimal', 'corporate'];
if (!validThemes.includes(args.theme)) {
errors.push(`Invalid theme '${args.theme}'. Must be one of: ${validThemes.join(', ')}`);
}
}
// Validate project name if provided
if (args.name) {
if (!/^[a-zA-Z0-9-_]+$/.test(args.name)) {
errors.push('Project name must contain only alphanumeric characters, hyphens, and underscores');
}
}
return {
valid: errors.length === 0,
errors,
};
}
/**
* Main CLI execution function
*/
async function main(): Promise<void> {
try {
// Handle help flag
if (args.help) {
displayHelp();
process.exit(0);
}
// Handle version flag
if (args.version) {
displayVersion();
process.exit(0);
}
// Validate arguments
const validation = validateArgs(args);
if (!validation.valid) {
console.error('ā Invalid arguments:');
validation.errors.forEach(error => console.error(` ⢠${error}`));
console.error('\nUse --help for usage information.');
process.exit(1);
}
// Convert parsed arguments to CLI options
const cliOptions: CLIOptions = {
name: args.name as string | undefined,
template: args.template as any,
theme: args.theme as any,
output: args.output as string | undefined,
skipPrompts: args['skip-prompts'] as boolean | undefined,
verbose: args.verbose as boolean | undefined,
dryRun: args['dry-run'] as boolean | undefined,
overwrite: args.overwrite as boolean | undefined,
skipInstall: args['skip-install'] as boolean | undefined,
skipGit: args['skip-git'] as boolean | undefined,
};
// Run the CLI
await runCLI(cliOptions);
} catch (error) {
console.error('ā Fatal error:', error instanceof Error ? error.message : 'Unknown error');
if (args.verbose && error instanceof Error && error.stack) {
console.error('\nStack trace:');
console.error(error.stack);
}
process.exit(1);
}
}
// Execute main function
main().catch((error) => {
console.error('ā Unhandled error:', error);
process.exit(1);
});