Your music, beautifully tracked. All yours. (coming soon) teal.fm
teal-fm atproto

Refactor lexicon generation with improved error handling

Changed files
+92 -62
tools
lexicon-cli
src
commands
+92 -62
tools/lexicon-cli/src/commands/generate.ts
··· 1 - import { execa } from 'execa'; 2 - import { existsSync } from 'fs'; 3 - import { join } from 'path'; 4 - import pc from 'picocolors'; 5 - import { findWorkspaceRoot } from '../utils/workspace.js'; 1 + import { existsSync } from "fs"; 2 + import { join } from "path"; 3 + import { execa } from "execa"; 4 + import pc from "picocolors"; 5 + 6 + import { findWorkspaceRoot } from "../utils/workspace.js"; 6 7 7 8 interface GenerateOptions { 8 9 tsOnly?: boolean; ··· 12 13 13 14 export async function generate(options: GenerateOptions = {}) { 14 15 const workspaceRoot = findWorkspaceRoot(); 15 - 16 - console.log(pc.blue('🔧 Generating lexicon types...')); 17 - 16 + 17 + console.log(pc.blue("🔧 Generating lexicon types...")); 18 + 18 19 try { 19 20 if (!options.rustOnly) { 20 21 await generateTypeScript(workspaceRoot, options.force); 21 22 } 22 - 23 + 23 24 if (!options.tsOnly) { 24 25 await generateRust(workspaceRoot, options.force); 25 26 } 26 - 27 - console.log(pc.green('✅ Lexicon generation complete!')); 27 + 28 + console.log(pc.green("✅ Lexicon generation complete!")); 28 29 } catch (error) { 29 - console.error(pc.red('❌ Generation failed:'), error instanceof Error ? error.message : String(error)); 30 + console.error( 31 + pc.red("❌ Generation failed:"), 32 + error instanceof Error ? error.message : String(error), 33 + ); 30 34 process.exit(1); 31 35 } 32 36 } 33 37 34 38 async function generateTypeScript(workspaceRoot: string, force?: boolean) { 35 - const lexiconsPath = join(workspaceRoot, 'lexicons'); 36 - 39 + const lexiconsPath = join(workspaceRoot, "lexicons"); 40 + 37 41 if (!existsSync(lexiconsPath)) { 38 - throw new Error('Lexicons directory not found at workspace root'); 42 + throw new Error("Lexicons directory not found at workspace root"); 39 43 } 40 - 44 + 41 45 // Check if packages/lexicons exists for TypeScript generation 42 - const packagesLexiconsPath = join(workspaceRoot, 'packages/lexicons'); 46 + const packagesLexiconsPath = join(workspaceRoot, "packages/lexicons"); 43 47 if (!existsSync(packagesLexiconsPath)) { 44 - console.log(pc.yellow(' ⚠️ TypeScript lexicons package not found, skipping TypeScript generation')); 48 + console.log( 49 + pc.yellow( 50 + " ⚠️ TypeScript lexicons package not found, skipping TypeScript generation", 51 + ), 52 + ); 45 53 return; 46 54 } 47 - 48 - console.log(pc.cyan(' 📦 Generating TypeScript types...')); 49 - 55 + 56 + console.log(pc.cyan(" 📦 Generating TypeScript types...")); 57 + 50 58 try { 51 - await execa('pnpm', ['lex:gen-server'], { 59 + await execa("pnpm", ["lex:gen-server"], { 52 60 cwd: packagesLexiconsPath, 53 - stdio: 'inherit' 61 + stdio: "inherit", 54 62 }); 55 - console.log(pc.green(' ✓ TypeScript types generated')); 63 + console.log(pc.green(" ✓ TypeScript types generated")); 56 64 } catch (error) { 57 - throw new Error(`TypeScript generation failed: ${error instanceof Error ? error.message : String(error)}`); 65 + throw new Error( 66 + `TypeScript generation failed: ${error instanceof Error ? error.message : String(error)}`, 67 + ); 58 68 } 59 69 } 60 70 61 71 async function generateRust(workspaceRoot: string, force?: boolean) { 62 - const typesPath = join(workspaceRoot, 'services/types'); 63 - const lexiconsPath = join(workspaceRoot, 'lexicons'); 64 - 72 + const typesPath = join(workspaceRoot, "services/types"); 73 + const lexiconsPath = join(workspaceRoot, "lexicons"); 74 + 65 75 if (!existsSync(typesPath)) { 66 - throw new Error('Rust types service not found'); 76 + throw new Error("Rust types service not found"); 67 77 } 68 - 78 + 69 79 if (!existsSync(lexiconsPath)) { 70 - throw new Error('Lexicons directory not found at workspace root'); 80 + throw new Error("Lexicons directory not found at workspace root"); 71 81 } 72 - 73 - console.log(pc.cyan(' 🦀 Generating Rust types...')); 74 - 82 + 83 + console.log(pc.cyan(" 🦀 Generating Rust types...")); 84 + 75 85 try { 76 86 // Check if esquema-cli is available 77 87 try { 78 - await execa('esquema-cli', ['--version'], { stdio: 'pipe' }); 88 + await execa("esquema-cli", ["--version"], { stdio: "pipe" }); 79 89 } catch { 80 - console.log(pc.yellow(' ⚠️ esquema-cli not found. Installing...')); 90 + console.log(pc.yellow(" ⚠️ esquema-cli not found. Installing...")); 81 91 try { 82 - await execa('cargo', [ 83 - 'install', 84 - 'esquema-cli', 85 - '--git', 86 - 'https://github.com/fatfingers23/esquema.git' 87 - ], { 88 - stdio: 'inherit' 89 - }); 90 - console.log(pc.green(' ✓ esquema-cli installed successfully')); 92 + await execa( 93 + "cargo", 94 + [ 95 + "install", 96 + "esquema-cli", 97 + "--git", 98 + "https://github.com/fatfingers23/esquema.git", 99 + ], 100 + { 101 + stdio: "inherit", 102 + }, 103 + ); 104 + console.log(pc.green(" ✓ esquema-cli installed successfully")); 91 105 } catch (installError) { 92 - throw new Error('Failed to install esquema-cli. Please install manually: cargo install esquema-cli --git https://github.com/fatfingers23/esquema.git'); 106 + throw new Error( 107 + "Failed to install esquema-cli. Please install manually: cargo install esquema-cli --git https://github.com/fatfingers23/esquema.git", 108 + ); 93 109 } 94 110 } 95 - 96 - await execa('esquema-cli', [ 97 - 'generate', 98 - 'local', 99 - '--lexdir', 100 - lexiconsPath, 101 - '--outdir', 102 - join(typesPath, 'src') 103 - ], { 104 - cwd: typesPath, 105 - stdio: 'inherit' 106 - }); 107 - 108 - console.log(pc.green(' ✓ Rust types generated')); 111 + 112 + // create typespath/src if it doesn't exist 113 + if (!existsSync(join(typesPath, "src"))) { 114 + console.log(pc.yellow(" Creating src directory for Rust types...")); 115 + await execa("mkdir", ["-p", join(typesPath, "src")], { 116 + stdio: "inherit", 117 + }); 118 + } 119 + 120 + await execa( 121 + "esquema-cli", 122 + [ 123 + "generate", 124 + "local", 125 + "--lexdir", 126 + lexiconsPath, 127 + "--outdir", 128 + join(typesPath, "src"), 129 + ], 130 + { 131 + cwd: typesPath, 132 + stdio: "inherit", 133 + }, 134 + ); 135 + 136 + console.log(pc.green(" ✓ Rust types generated")); 109 137 } catch (error) { 110 - throw new Error(`Rust generation failed: ${error instanceof Error ? error.message : String(error)}`); 138 + throw new Error( 139 + `Rust generation failed: ${error instanceof Error ? error.message : String(error)}`, 140 + ); 111 141 } 112 - } 142 + }