Files
2026-06-25 19:06:59 -04:00

48 lines
1.8 KiB
JavaScript

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.');