@bunli/generator
Generate TypeScript definitions from CLI commands for enhanced developer experience
@bunli/generator
Generate TypeScript definitions from your CLI commands to enable advanced patterns like CLI wrappers, documentation generation, and command analytics.
@bunli/generator has minimal dependencies and uses Babel for AST parsing to extract command metadata from your TypeScript files.
Installation
bun add @bunli/generatornpm install @bunli/generatorpnpm add @bunli/generatorFeatures
- 🚀 Fast Generation - Uses Babel for efficient AST parsing
- 📝 Type Safety - Generates fully typed TypeScript definitions
- 🔄 Watch Mode - Automatically regenerate on file changes
- 🎯 Command Discovery - Scans and parses command files automatically
- 🔌 Plugin Integration - Works seamlessly with Bunli's plugin system
- ⚡ Build Integration - Integrates with
bunli devandbunli build - 🛠️ CLI Tool - Standalone
bunli generatecommand
Core APIs
Generator Class
The main class for generating TypeScript definitions:
import { Generator } from '@bunli/generator'
const generator = new Generator({
commandsDir: './commands',
outputFile: './.bunli/commands.gen.ts',
config: {}, // Optional config object
generateReport: false // Optional report generation
})
// Generate types once
await generator.run()
// Generate with specific options
await generator.run({
type: 'update',
path: './commands/new-command.ts'
})CommandScanner
Scans directories for command files:
import { CommandScanner } from '@bunli/generator'
const scanner = new CommandScanner()
const files = await scanner.scanCommands('./commands')
console.log(files) // ['greet.ts', 'deploy.ts', 'test.ts']parseCommand Function
Parse individual command files:
import { parseCommand } from '@bunli/generator'
const commandData = await parseCommand('./commands/greet.ts', './commands', './.bunli/commands.gen.ts')
console.log(commandData)
// {
// name: 'greet',
// description: 'Greet someone',
// options: { ... },
// alias: ['hello'],
// filePath: './commands/greet.ts',
// importPath: '../commands/greet',
// exportPath: 'greet'
// }buildTypes Function
Build TypeScript definitions from command data:
import { buildTypes } from '@bunli/generator'
const commands = [
{ name: 'greet', description: 'Greet someone', options: { ... } },
{ name: 'deploy', description: 'Deploy app', options: { ... } }
]
const types = buildTypes(commands)
console.log(types) // Generated TypeScript codePlugin Integration
bunliCodegenPlugin
Use as a Bun plugin for build integration:
import { bunliCodegenPlugin } from '@bunli/generator'
// In your build configuration
export default {
plugins: [
bunliCodegenPlugin({
commandsDir: './commands',
output: './.bunli/commands.gen.ts'
})
]
}CLI Integration
The generator is automatically integrated with Bunli CLI commands:
# Development mode with watch
bunli dev
# Build with type generation
bunli build
# Standalone generation
bunli generate --watchConfiguration Options
Generator Options
Configuration for type generation
| Option | Type | Default | Description |
|---|---|---|---|
commandsDir | string | './commands' | Directory to scan for command files |
outputFile | string | './.bunli/commands.gen.ts' | Output file for generated types |
watch | boolean | false | Watch for file changes |
include | string[] | ['**/*.ts', '**/*.js'] | File patterns to include |
exclude | string[] | ['**/*.test.*', '**/*.spec.*'] | File patterns to exclude |
Generated Output Structure
The generator creates a comprehensive TypeScript API:
GeneratedCLI Interface
interface GeneratedCLI {
register(cli?: CLI<any>): GeneratedCLI
list(): Array<{
name: GeneratedNames
command: Command<any>
metadata: GeneratedCommandMeta
}>
get<Name extends GeneratedNames>(name: Name): Command<any>
getMetadata<Name extends GeneratedNames>(name: Name): GeneratedCommandMeta
getFlags<Name extends GeneratedNames>(name: Name): CommandOptions<Name>
getFlagsMeta<Name extends GeneratedNames>(name: Name): Record<string, GeneratedOptionMeta>
withCLI(cli: CLI<any>): { execute(name: string, options: unknown): Promise<void> }
}Helper Functions
// Get command metadata by name
function getCommandApi<Name extends GeneratedNames>(name: Name): GeneratedCommandMeta
// Get all command names
function getCommandNames(): GeneratedNames[]
// List all commands with metadata
function listCommands(): GeneratedNames[]
// Get typed flags for a command
function getTypedFlags<Name extends GeneratedNames>(name: Name): CommandOptions<Name>
// Validate command arguments
function validateCommand<Name extends GeneratedNames>(name: Name, flags: Record<string, unknown>): ValidationResult
// Find commands by name or description
function findCommandByName<Name extends GeneratedNames>(name: Name): CommandInfo
function findCommandsByDescription(searchTerm: string): CommandInfo[]Usage
Basic Generation
import { Generator } from '@bunli/generator'
const generator = new Generator({
commandsDir: './src/commands',
outputFile: './.bunli/commands.gen.ts'
})
await generator.run()Watch Mode
Watch mode is handled by the CLI command:
bunli generate --watchPerformance
- Scanning: ~10ms for 50 command files
- Parsing: ~5ms per command file
- Generation: ~2ms for 20 commands
- Watch Mode: <1ms incremental updates
API Reference
Generator
class Generator {
constructor(options: GeneratorOptions)
// Generate types once
run(options?: RunOptions): Promise<void>
// Watch for changes
watch(): Promise<void>
// Stop watching
stop(): void
}GeneratorOptions
interface GeneratorOptions {
commandsDir: string
outputFile: string
config?: any
generateReport?: boolean
}RunOptions
interface RunOptions {
type?: 'update' | 'delete'
path?: string
}CommandMetadata
interface CommandMetadata {
name: string
description: string
alias?: string | string[]
options?: Record<string, OptionMetadata>
commands?: CommandMetadata[]
filePath: string
importPath: string
exportPath: string
hasHandler?: boolean
hasRender?: boolean
}
interface OptionMetadata {
type: string
required: boolean
hasDefault: boolean
default?: any
description?: string
short?: string
schema?: any
validator?: string
}Integration
With Bunli CLI
// bunli.config.ts
import { defineConfig } from '@bunli/core'
export default defineConfig({
name: 'my-cli',
version: '1.0.0',
})With Custom Build Script
import { Generator } from '@bunli/generator'
const generator = new Generator({
commandsDir: './src/commands',
outputFile: './.bunli/commands.gen.ts'
})
await generator.run()Troubleshooting
Generation fails:
- Check that command files use
defineCommand - Verify TypeScript syntax is correct
Types not updating:
- Use
bunli generate --watchfor development - Check file paths are correct
Import errors:
- Ensure generated file exists at
./.bunli/commands.gen.ts - Verify TypeScript configuration
See Also
- Type Generation Guide - Complete guide to using generated types
- bunli CLI - CLI toolchain with integrated generation
- Configuration - Configure code generation
- @bunli/core - Core framework with type utilities