diff --git a/scripts/i18n/generate-qa-checklist.mjs b/scripts/i18n/generate-qa-checklist.mjs index e8e02cbbb6..1d6cdaef25 100644 --- a/scripts/i18n/generate-qa-checklist.mjs +++ b/scripts/i18n/generate-qa-checklist.mjs @@ -7,6 +7,7 @@ const ROOT = process.cwd(); const APP_DIR = path.join(ROOT, "src", "app"); const MESSAGES_DIR = path.join(ROOT, "src", "i18n", "messages"); const REPORTS_DIR = path.join(ROOT, "docs", "reports"); +const I18N_README_DIR = path.join(ROOT, "docs", "i18n"); const PRIORITY_LOCALES = ["es", "fr", "de", "ja", "ar"]; @@ -187,36 +188,43 @@ async function runAutomatedChecks() { } const readmeLabelChecks = []; - const readmeExpectedPrefix = { - "README.es.md": "๐ŸŒ **Disponible en:**", - "README.fr.md": "๐ŸŒ **Disponible en :**", - "README.de.md": "๐ŸŒ **Verfugbar in:**", - "README.ja.md": "๐ŸŒ **ๅฏพๅฟœ่จ€่ชž:**", - "README.ar.md": "๐ŸŒ **ู…ุชูˆูุฑ ุจุงู„ู„ุบุงุช:**", - }; + // Check that README has language selector line with emoji flag + const expectedPattern = /^๐ŸŒ \*\*Languages:\*\*/; - for (const [file, expectedPrefix] of Object.entries(readmeExpectedPrefix)) { - const content = await fs.readFile(path.join(ROOT, file), "utf8"); - const line = content.split("\n").find((entry) => entry.startsWith("๐ŸŒ **")) || ""; + for (const code of PRIORITY_LOCALES) { + const readmePath = path.join(I18N_README_DIR, code, "README.md"); + let content = ""; + try { + content = await fs.readFile(readmePath, "utf8"); + } catch { + // Skip if README doesn't exist + continue; + } + const line = content.split("\n").find((entry) => entry.startsWith("๐ŸŒ **Languages:**")) || ""; + const ok = expectedPattern.test(line); - // Accept both ASCII-only and umlaut versions for DE prefix. - const ok = - file !== "README.de.md" - ? line.startsWith(expectedPrefix) - : line.startsWith("๐ŸŒ **Verfรผgbar in:**") || line.startsWith(expectedPrefix); - - readmeLabelChecks.push({ file, ok, line }); + readmeLabelChecks.push({ file: `docs/i18n/${code}/README.md`, ok, line }); } - const jaReadme = await fs.readFile(path.join(ROOT, "README.ja.md"), "utf8"); - const arReadme = await fs.readFile(path.join(ROOT, "README.ar.md"), "utf8"); + let anchorLineRemoved = true; + let brAppendixRemoved = true; - const anchorLineRemoved = - !jaReadme.includes("**[English](#-omniroute--the-free-ai-gateway)**") && - !arReadme.includes("**[English](#-omniroute--the-free-ai-gateway)**"); - - const brAppendixRemoved = - !jaReadme.includes("## ๐Ÿ‡ง๐Ÿ‡ท OmniRoute") && !arReadme.includes("## ๐Ÿ‡ง๐Ÿ‡ท OmniRoute"); + // Check RTL languages (ar, ja) for legacy content + const rtlLanguages = ["ar", "ja"]; + for (const code of rtlLanguages) { + const readmePath = path.join(I18N_README_DIR, code, "README.md"); + try { + const content = await fs.readFile(readmePath, "utf8"); + if (content.includes("**[English](#-omniroute--the-free-ai-gateway)**")) { + anchorLineRemoved = false; + } + if (content.includes("## ๐Ÿ‡ง๐Ÿ‡ท OmniRoute")) { + brAppendixRemoved = false; + } + } catch { + // Skip if README doesn't exist + } + } return { localeCodes, @@ -263,7 +271,7 @@ async function main() { } automatedChecksLines.push( - `- Prefixo local do seletor de idiomas em README (es/fr/de/ja/ar): **${automated.readmeLabelChecks.every((item) => item.ok) ? "OK" : "FALHAS"}**`, + `- Language selector (๐ŸŒ **Languages:**) in README (es/fr/de/ja/ar): **${automated.readmeLabelChecks.every((item) => item.ok) ? "OK" : "FALHAS"}**`, `- Linha legacy EN/PT removida em ja/ar: **${automated.anchorLineRemoved ? "OK" : "PENDENTE"}**`, `- Apรชndice "## ๐Ÿ‡ง๐Ÿ‡ท OmniRoute" removido em ja/ar: **${automated.brAppendixRemoved ? "OK" : "PENDENTE"}**`, "- RTL habilitado globalmente para `ar` e `he` via `dir=rtl` no layout."