diff --git a/scripts/docs-site/build.mjs b/scripts/docs-site/build.mjs index cea35cf655..1255f03344 100644 --- a/scripts/docs-site/build.mjs +++ b/scripts/docs-site/build.mjs @@ -4,7 +4,7 @@ import path from "node:path"; import { createHash } from "node:crypto"; import { Worker } from "node:worker_threads"; -import { ignoredDocDirs, ignoredDocFiles, localeLabels, mintlifyLocaleToDir, rtlLocales } from "./config.mjs"; +import { ignoredDocDirs, ignoredDocFiles, localeFlags, localeLabels, mintlifyLocaleToDir, rtlLocales } from "./config.mjs"; import { siteCss, siteJs } from "./assets.mjs"; import { createMarkdownRenderer, renderMdxish } from "./mdx-ish.mjs"; import { editSourceUrlForPage, frontmatterSourcePath, readSourceMetadata } from "./edit-source.mjs"; @@ -72,27 +72,6 @@ if (previewMode) { pageByKey = new Map(pages.map((page) => [pageKey(page.locale, page.slug), page])); navByLocale = new Map(locales.map((locale) => [locale.code, buildNav(locale)])); } -const localeFlags = { - en: "🇺🇸", - "zh-CN": "🇨🇳", - "zh-TW": "🇨🇳", - "ja-JP": "🇯🇵", - es: "🇪🇸", - "pt-BR": "🇧🇷", - ko: "🇰🇷", - de: "🇩🇪", - fr: "🇫🇷", - ar: "🇸🇦", - it: "🇮🇹", - vi: "🇻🇳", - nl: "🇳🇱", - tr: "🇹🇷", - uk: "🇺🇦", - id: "🇮🇩", - pl: "🇵🇱", - fa: "🇮🇷", - th: "🇹🇭" -}; const localePickerLabels = { "pt-BR": "Português (BR)" }; diff --git a/scripts/docs-site/config.mjs b/scripts/docs-site/config.mjs index c5365cc479..a3bbea47ed 100644 --- a/scripts/docs-site/config.mjs +++ b/scripts/docs-site/config.mjs @@ -8,6 +8,7 @@ export const localeLabels = { ko: "한국어", de: "Deutsch", fr: "Français", + hi: "हिन्दी", ar: "العربية", it: "Italiano", vi: "Tiếng Việt", @@ -17,9 +18,34 @@ export const localeLabels = { uk: "Українська", id: "Bahasa Indonesia", pl: "Polski", + ru: "Русский", th: "ไทย" }; +export const localeFlags = { + en: "🇺🇸", + "zh-CN": "🇨🇳", + "zh-TW": "🇨🇳", + "ja-JP": "🇯🇵", + es: "🇪🇸", + "pt-BR": "🇧🇷", + ko: "🇰🇷", + de: "🇩🇪", + fr: "🇫🇷", + hi: "🇮🇳", + ar: "🇸🇦", + it: "🇮🇹", + vi: "🇻🇳", + nl: "🇳🇱", + fa: "🇮🇷", + tr: "🇹🇷", + uk: "🇺🇦", + id: "🇮🇩", + pl: "🇵🇱", + ru: "🇷🇺", + th: "🇹🇭" +}; + export const mintlifyLocaleToDir = { en: "en", "zh-Hans": "zh-CN", @@ -30,6 +56,7 @@ export const mintlifyLocaleToDir = { ko: "ko", de: "de", fr: "fr", + hi: "hi", ar: "ar", it: "it", vi: "vi", @@ -39,6 +66,7 @@ export const mintlifyLocaleToDir = { uk: "uk", id: "id", pl: "pl", + ru: "ru", th: "th" }; diff --git a/scripts/docs-site/smoke.mjs b/scripts/docs-site/smoke.mjs index 3c1f40211a..8d307da955 100644 --- a/scripts/docs-site/smoke.mjs +++ b/scripts/docs-site/smoke.mjs @@ -3,7 +3,7 @@ import fs from "node:fs"; import path from "node:path"; import { execFileSync } from "node:child_process"; -import { localeLabels } from "./config.mjs"; +import { ignoredDocDirs, localeFlags, localeLabels, mintlifyLocaleToDir } from "./config.mjs"; import { editSourceUrlForPage, frontmatterSourcePath, readSourceMetadata } from "./edit-source.mjs"; import { parseFrontmatter } from "./frontmatter.mjs"; @@ -58,6 +58,11 @@ const poison = [ /彩神马争霸/u ]; +for (const locale of activeLocaleCodes()) { + if (!localeLabels[locale]) throw new Error(`locale metadata: missing label for ${locale}`); + if (!localeFlags[locale]) throw new Error(`locale metadata: missing flag for ${locale}`); +} + for (const rel of required) { const file = path.join(site, rel); if (!fs.existsSync(file)) throw new Error(`missing ${rel}`); @@ -176,6 +181,9 @@ if (!/data-language-picker/.test(index) || !/class="language-option active"[^>]* if (!/Português \(BR\)/.test(index)) { throw new Error("index: language picker labels were not rendered"); } +if (!/🇮🇳/.test(index) || !/हिन्दी/.test(index) || !/🇷🇺/.test(index) || !/Русский/.test(index)) { + throw new Error("index: Hindi and Russian language picker metadata was not rendered"); +} if ( !/data-docs-chat/.test(index) || !/OPENCLAW_DOCS_CHAT_API/.test(index) || @@ -831,3 +839,13 @@ function walkFiles(dir) { return entry.isDirectory() ? walkFiles(full) : [full]; }); } + +function activeLocaleCodes() { + const docsConfig = JSON.parse(fs.readFileSync(path.join(docsDir, "docs.json"), "utf8")); + const configured = (docsConfig.navigation?.languages ?? []) + .map((entry) => mintlifyLocaleToDir[entry.language] ?? entry.language); + const knownLocaleDirs = fs.readdirSync(docsDir, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory() && !ignoredDocDirs.has(dirent.name) && localeLabels[dirent.name]) + .map((dirent) => dirent.name); + return new Set(["en", ...configured, ...knownLocaleDirs]); +}