Add generators: code, completion, and docs generators

This commit is contained in:
2026-01-30 07:10:13 +00:00
parent 496e73c8a1
commit 72ae630c3f

View File

@@ -0,0 +1,89 @@
import * as fs from 'fs';
import * as path from 'path';
import Handlebars from 'handlebars';
import type { CLISpec, ShellType } from '../types/spec.js';
const TEMPLATE_DIR = path.resolve(process.cwd(), 'src', 'templates');
function getTemplatePath(shell: ShellType): string {
return path.join(TEMPLATE_DIR, `completion-${shell}.handlebars`);
}
function getTemplateContent(shell: ShellType): string {
const templatePath = getTemplatePath(shell);
if (!fs.existsSync(templatePath)) {
throw new Error(`Completion template not found: ${templatePath}`);
}
return fs.readFileSync(templatePath, 'utf-8');
}
function compileTemplate(content: string): Handlebars.TemplateDelegate {
Handlebars.registerHelper('escape', function (str: string) {
return str.replace(/'/g, "'\\''").replace(/\n/g, ' ');
});
Handlebars.registerHelper('defaultValue', function (value: unknown) {
if (value === undefined || value === null) return '';
return String(value);
});
return Handlebars.compile(content, { noEscape: true });
}
export interface CompletionResult {
success: boolean;
script?: string;
error?: string;
}
export function generateCompletion(spec: CLISpec, shell: ShellType): CompletionResult {
try {
const templateContent = getTemplateContent(shell);
const template = compileTemplate(templateContent);
const script = template({ spec });
return { success: true, script };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error during completion generation',
};
}
}
export function getCompletionFileName(spec: CLISpec, shell: ShellType): string {
const baseName = spec.bin || spec.name;
const extensions: Record<ShellType, string> = {
'bash': 'bash',
'zsh': 'zsh',
'fish': 'fish',
};
return `_${baseName}.${extensions[shell]}`;
}
export function getInstallInstructions(spec: CLISpec, shell: ShellType): string {
const fileName = getCompletionFileName(spec, shell);
switch (shell) {
case 'bash':
return `# Add to ~/.bashrc or /etc/bash_completion.d/
source ${fileName}
# Or for user-specific installation:
echo "source $(pwd)/${fileName}" >> ~/.bashrc`;
case 'zsh':
return `# Add to ~/.zshrc or create file in ~/.zsh/completion/
mkdir -p ~/.zsh/completion
cp ${fileName} ~/.zsh/completion/
echo "fpath=(~/.zsh/completion \\$$fpath)" >> ~/.zshrc
autoload -U compinit
compinit`;
case 'fish':
return `# Add to ~/.config/fish/completions/
mkdir -p ~/.config/fish/completions/
cp ${fileName} ~/.config/fish/completions/`;
default:
return `Unknown shell: ${shell}`;
}
}