import fs from "fs"; import * as glob from "glob"; import { syncFile } from "./syncFile"; async function main() { const args = process.argv.slice(2); if (args.length < 2) { console.log(` Usage: bun index.ts glob-pattern [--dry-run] Examples: # Create mapping and update files in the same directory bun index.ts dictionaries/en.json 'apps/**/*.{ts,tsx}' # Dry run - show what would be changed without writing to files bun index.ts dictionaries/en.json apps/**/*.{ts,tsx} --dry-run `); process.exit(1); } // Load your messages from the JSON file const englishTranslations = process.argv[2] || "./locales/en.json"; const translations = flattenTranslations( JSON.parse(fs.readFileSync(englishTranslations, "utf-8")) as Record< string, string | { translation: string } > ); const isDryRun = args.includes("--dry-run"); const globPattern = args[1]; // Find all component files const componentFiles = glob.sync(globPattern); console.log( `Found ${componentFiles.length} files to sync using ${globPattern}` ); let filesUpdated = 0; for (const filePath of componentFiles) { if (isDryRun) { console.log(`(dry run) Would sync file: ${filePath}`); continue; } const { updated } = syncFile({ path: filePath, translations }); if (updated) { filesUpdated++; console.log(`Updated: ${filePath}`); } } console.log(`\n✓ Sync complete! Updated ${filesUpdated} file(s)`); } function flattenTranslations( translations: Record ): Record { const flat = Object.entries(translations).reduce( (acc, [key, val]) => { if (typeof val === "string") { acc[key] = val; } else if ( val && typeof val === "object" && "translation" in val && typeof val.translation === "string" ) { acc[key] = val.translation; } return acc; }, {} as Record ); return flat; } // Run CLI if this file is executed directly if (require.main === module) { main(); }