Your music, beautifully tracked. All yours. (coming soon) teal.fm
teal-fm atproto
at fix-compose-path 114 lines 3.9 kB view raw
1import { readFileSync, existsSync } from 'fs'; 2import { join } from 'path'; 3import { glob } from 'glob'; 4import pc from 'picocolors'; 5import { findWorkspaceRoot } from '../utils/workspace.js'; 6 7export async function validate() { 8 const workspaceRoot = findWorkspaceRoot(); 9 10 console.log(pc.blue('🔍 Validating lexicon types...')); 11 12 try { 13 await validateTypeScriptGeneration(workspaceRoot); 14 await validateRustGeneration(workspaceRoot); 15 await validateConsistency(workspaceRoot); 16 17 console.log(pc.green('✅ All validations passed!')); 18 } catch (error) { 19 console.error(pc.red('❌ Validation failed:'), error instanceof Error ? error.message : String(error)); 20 process.exit(1); 21 } 22} 23 24async function validateTypeScriptGeneration(workspaceRoot: string) { 25 console.log(pc.cyan(' 📦 Validating TypeScript generation...')); 26 27 const lexiconsPath = join(workspaceRoot, 'lexicons'); 28 const packagesLexiconsPath = join(workspaceRoot, 'packages/lexicons'); 29 30 if (!existsSync(lexiconsPath)) { 31 throw new Error('Lexicons directory not found at workspace root'); 32 } 33 34 if (!existsSync(packagesLexiconsPath)) { 35 console.log(pc.yellow(' ⚠️ TypeScript lexicons package not found, skipping validation')); 36 return; 37 } 38 39 const typesPath = join(packagesLexiconsPath, 'src/types'); 40 41 if (!existsSync(typesPath)) { 42 throw new Error('TypeScript types directory not found'); 43 } 44 45 // Check if generated files exist for each source lexicon 46 const sourceFiles = await glob('**/*.json', { cwd: lexiconsPath }); 47 48 for (const sourceFile of sourceFiles) { 49 const namespace = sourceFile.replace('.json', '').replace(/\//g, '/'); 50 const expectedTypeFile = join(typesPath, namespace + '.ts'); 51 52 if (!existsSync(expectedTypeFile)) { 53 console.log(pc.yellow(` ⚠️ Missing TypeScript types for: ${sourceFile}`)); 54 } 55 } 56 57 console.log(pc.green(' ✓ TypeScript validation complete')); 58} 59 60async function validateRustGeneration(workspaceRoot: string) { 61 console.log(pc.cyan(' 🦀 Validating Rust generation...')); 62 63 const typesPath = join(workspaceRoot, 'services/types'); 64 const lexiconsPath = join(workspaceRoot, 'lexicons'); 65 const srcPath = join(typesPath, 'src'); 66 67 if (!existsSync(lexiconsPath)) { 68 throw new Error('Lexicons directory not found at workspace root'); 69 } 70 71 if (!existsSync(srcPath)) { 72 throw new Error('Rust src directory not found'); 73 } 74 75 // Check if Cargo.toml exists 76 const cargoTomlPath = join(typesPath, 'Cargo.toml'); 77 if (!existsSync(cargoTomlPath)) { 78 throw new Error('Cargo.toml not found in types directory'); 79 } 80 81 console.log(pc.green(' ✓ Rust validation complete')); 82} 83 84async function validateConsistency(workspaceRoot: string) { 85 console.log(pc.cyan(' 🔄 Validating cross-language consistency...')); 86 87 // Use centralized lexicons directory 88 const lexiconsPath = join(workspaceRoot, 'lexicons'); 89 90 if (!existsSync(lexiconsPath)) { 91 throw new Error('Cannot validate consistency - lexicons directory not found'); 92 } 93 94 // Count lexicon files 95 const lexiconFiles = await glob('**/*.json', { cwd: lexiconsPath }); 96 97 console.log(pc.gray(` Lexicon files found: ${lexiconFiles.length} files`)); 98 99 // Check if TypeScript and Rust generated types exist 100 const tsTypesPath = join(workspaceRoot, 'packages/lexicons/src/types'); 101 const rustTypesPath = join(workspaceRoot, 'services/types/src'); 102 103 let tsExists = existsSync(tsTypesPath); 104 let rustExists = existsSync(rustTypesPath); 105 106 console.log(pc.gray(` TypeScript types: ${tsExists ? 'Found' : 'Not found'}`)); 107 console.log(pc.gray(` Rust types: ${rustExists ? 'Found' : 'Not found'}`)); 108 109 if (!tsExists && !rustExists) { 110 console.log(pc.yellow(' ⚠️ No generated types found for either language')); 111 } 112 113 console.log(pc.green(' ✓ Consistency validation complete')); 114}