import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { fail, flatten, pass, repositoryRoot } from './lib.mjs'; const localeRoot = path.join(repositoryRoot, 'src', 'content', 'locales'); const locales = ['en', 'fr', 'ar']; const files = ['homepage.json', 'shell.json']; const errors = []; for (const file of files) { const catalogs = new Map(); for (const locale of locales) { const parsed = JSON.parse(await readFile(path.join(localeRoot, locale, file), 'utf8')); catalogs.set(locale, flatten(parsed)); } const sourceKeys = [...catalogs.get('en').keys()]; for (const locale of locales) { const catalog = catalogs.get(locale); const keys = [...catalog.keys()]; const missing = sourceKeys.filter((key) => !catalog.has(key)); const extra = keys.filter((key) => !catalogs.get('en').has(key)); if (missing.length) errors.push(`${locale}/${file} missing: ${missing.join(', ')}`); if (extra.length) errors.push(`${locale}/${file} extra: ${extra.join(', ')}`); for (const [key, value] of catalog) { if (typeof value === 'string' && value.trim().length === 0) { errors.push(`${locale}/${file}:${key} is empty.`); } } } } const expectedDirections = { en: 'ltr', fr: 'ltr', ar: 'rtl' }; for (const locale of locales) { const homepage = JSON.parse( await readFile(path.join(localeRoot, locale, 'homepage.json'), 'utf8'), ); if (homepage.meta.dir !== expectedDirections[locale]) { errors.push(`${locale} metadata direction must be ${expectedDirections[locale]}.`); } if (JSON.stringify(homepage).includes('homePageCar')) { errors.push(`${locale} implementation catalog still contains the retired project name.`); } } if (errors.length > 0) fail(errors); else pass('English, French, and Arabic catalogs have exact key parity and valid direction metadata.');