create-roadkit
Version:
Beautiful Next.js roadmap website generator with full-screen kanban boards, dark/light mode, and static export
142 lines (121 loc) ⢠3.83 kB
text/typescript
/**
* RoadKit CLI - Beautiful Next.js roadmap website generator
*/
import { generateRoadmapProject, ProjectConfig } from '../src/core/template-generator.js'
import { intro, outro, text, isCancel, cancel } from '@clack/prompts'
import path from 'path'
/**
* Show help message
*/
function showHelp() {
console.log(`
š RoadKit - Beautiful Next.js Roadmap Generator
Usage: roadkit [project-name]
Arguments:
project-name Name of the project to create
Examples:
roadkit # Interactive mode
roadkit my-awesome-roadmap # Direct mode
Features:
⨠Beautiful kanban board layout
š± Fully responsive design
š Dark/light mode toggle
š¦ Static export ready
š Instant dev updates
`)
}
/**
* Interactive CLI mode - prompt user for project name
*/
async function interactiveMode(): Promise<string> {
intro('š Welcome to RoadKit!')
const projectNameInput = await text({
message: "What's your project name?",
placeholder: 'my-awesome-roadmap',
validate: (value) => {
if (!value) return 'Project name is required'
if (!/^[a-zA-Z0-9-_]+$/.test(value)) {
return 'Project name must contain only alphanumeric characters, hyphens, and underscores'
}
}
})
if (isCancel(projectNameInput)) {
cancel('Operation cancelled')
process.exit(0)
}
return projectNameInput as string
}
// Parse command line arguments
const args = process.argv.slice(2)
// Handle help flag
if (args.includes('--help') || args.includes('-h')) {
showHelp()
process.exit(0)
}
let projectName: string
const outputDir = './'
// Generate the template
async function main() {
try {
// Get project name either from args or interactive mode
if (args.length === 0) {
// Interactive mode
projectName = await interactiveMode()
} else if (args.length === 1) {
// Direct mode with project name argument
projectName = args[0]
} else {
console.error('ā Too many arguments. Use --help for usage information.')
process.exit(1)
}
console.log('')
console.log('šÆ Generating Next.js roadmap project...')
console.log(` Project: ${projectName}`)
console.log(` TypeScript: Always enabled`)
console.log(` Output: ${path.resolve(outputDir)}`)
console.log('')
const config: ProjectConfig = {
name: projectName,
outputPath: path.resolve(outputDir),
theme: 'modern',
typescript: true,
features: {
analytics: false,
auth: false,
darkMode: true,
exportFeature: true
}
}
await generateRoadmapProject(config)
console.log('')
outro('ā
Generated Next.js roadmap at ./' + projectName)
console.log('')
console.log('š Next steps:')
console.log(` 1. cd ${projectName}`)
console.log(` 2. bun run dev # Recommended (fastest)`)
console.log(` or npm run dev # Also works`)
console.log(` 3. Open http://localhost:3000`)
console.log(` 4. Edit src/data/roadmap-data.ts to customize your roadmap`)
console.log('')
console.log('š Deployment:')
console.log(` ⢠Static: bun run export (then upload dist/ folder)`)
console.log(` ⢠Vercel: git push (auto-deploy)`)
console.log('')
console.log('š Resources:')
console.log(' ⢠https://nextjs.org/docs')
console.log(' ⢠https://tailwindcss.com/docs')
} catch (error) {
console.error('')
console.error('š„ Unexpected error occurred!')
console.error(` ${error instanceof Error ? error.message : 'Unknown error'}`)
if (error instanceof Error && error.stack) {
console.error('')
console.error('Stack trace:')
console.error(error.stack)
}
process.exit(1)
}
}
// Run the CLI
main()