mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-09 01:46:46 +08:00
* docs(i18n): translate documentation corpus to French (MUL-7637) Add French (.fr.mdx) translations for all 45 docs pages plus meta.fr.json navigation, mirroring the English source. Product and UI terms follow the in-app French locale at packages/views/locales/fr/ (issue -> tâche, run -> exécution, autopilot -> automatisation, Chat -> Discussion, Settings -> Paramètres, etc.). Status and role identifiers stay lowercase English per the conventions glossary, with the French UI label shown once where they are defined. Co-authored-by: multica-agent <[email protected]> * feat(docs): serve French docs locale (MUL-7637) Register fr in the docs i18n config and add the French Fumadocs chrome, language-switcher label, and home hero copy. Fumadocs maps fr to Orama's built-in French tokenizer, so search needs no custom localeMap entry. Co-authored-by: multica-agent <[email protected]> * feat(i18n): link French UI to French docs (MUL-7637) Route French users from the landing page, runtime guides, the autopilot webhook filter help, and the Slack/Lark/DingTalk/Telegram setup links to /docs/fr. The four integration tabs and the runtime helper each carried a copy of the same locale-prefix ternary; they now share docsLocalePrefix. Co-authored-by: multica-agent <[email protected]> * fix(i18n): localize remaining docs entry points (MUL-7637) French users still reached English docs from the Help menu, the Agents and Skills "Learn more" links, and the landing footer. The views links now use docsLocalePrefix; the landing dictionaries take the docs href from docsHrefForLocale, so locales that reuse another dictionary (French reuses English) still link to their own docs. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]>
119 lines
3.8 KiB
TypeScript
119 lines
3.8 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const existingDocs = vi.hoisted(() => new Set<string>());
|
|
|
|
vi.mock("node:fs", () => ({
|
|
existsSync: vi.fn((path: string) => {
|
|
const normalized = path.replaceAll("\\", "/");
|
|
return [...existingDocs].some((suffix) => normalized.endsWith(suffix));
|
|
}),
|
|
}));
|
|
|
|
const pages = new Map<string, { url: string }>([
|
|
["en:", { url: "/" }],
|
|
["zh:", { url: "/zh" }],
|
|
["ko:", { url: "/ko" }],
|
|
["ja:", { url: "/ja" }],
|
|
["fr:", { url: "/fr" }],
|
|
["en:agents", { url: "/agents" }],
|
|
["zh:agents", { url: "/zh/agents" }],
|
|
["ko:agents", { url: "/ko/agents" }],
|
|
["ja:agents", { url: "/ja/agents" }],
|
|
["fr:agents", { url: "/fr/agents" }],
|
|
]);
|
|
|
|
vi.mock("@/lib/source", () => ({
|
|
source: {
|
|
getPage: vi.fn((slugs: string[], lang: string) => {
|
|
return pages.get(`${lang}:${slugs.join("/")}`) ?? null;
|
|
}),
|
|
},
|
|
}));
|
|
|
|
beforeEach(() => {
|
|
existingDocs.clear();
|
|
existingDocs.add("index.mdx");
|
|
existingDocs.add("index.zh.mdx");
|
|
existingDocs.add("agents.mdx");
|
|
existingDocs.add("agents.zh.mdx");
|
|
});
|
|
|
|
describe("docsAlternates", () => {
|
|
it("omits Korean hreflang when no Korean MDX file exists for the page", async () => {
|
|
const { docsAlternates } = await import("./site");
|
|
|
|
expect(docsAlternates(["agents"])).toEqual({
|
|
canonical: "https://www.multica.ai/docs/agents",
|
|
languages: {
|
|
en: "https://www.multica.ai/docs/agents",
|
|
zh: "https://www.multica.ai/docs/zh/agents",
|
|
"x-default": "https://www.multica.ai/docs/agents",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("omits Korean hreflang even when source.getPage returns a page for Korean", async () => {
|
|
const { docsAlternates } = await import("./site");
|
|
|
|
expect(docsAlternates(["agents"]).languages).not.toHaveProperty("ko");
|
|
});
|
|
|
|
it("includes Korean hreflang when a real *.ko.mdx page exists", async () => {
|
|
existingDocs.add("agents.ko.mdx");
|
|
const { docsAlternates } = await import("./site");
|
|
|
|
expect(docsAlternates(["agents"])).toEqual({
|
|
canonical: "https://www.multica.ai/docs/agents",
|
|
languages: {
|
|
en: "https://www.multica.ai/docs/agents",
|
|
zh: "https://www.multica.ai/docs/zh/agents",
|
|
ko: "https://www.multica.ai/docs/ko/agents",
|
|
"x-default": "https://www.multica.ai/docs/agents",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("includes Japanese hreflang when a real *.ja.mdx page exists", async () => {
|
|
existingDocs.add("agents.ja.mdx");
|
|
const { docsAlternates } = await import("./site");
|
|
|
|
expect(docsAlternates(["agents"])).toEqual({
|
|
canonical: "https://www.multica.ai/docs/agents",
|
|
languages: {
|
|
en: "https://www.multica.ai/docs/agents",
|
|
zh: "https://www.multica.ai/docs/zh/agents",
|
|
ja: "https://www.multica.ai/docs/ja/agents",
|
|
"x-default": "https://www.multica.ai/docs/agents",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("includes French hreflang when a real *.fr.mdx page exists", async () => {
|
|
existingDocs.add("agents.fr.mdx");
|
|
const { docsAlternates } = await import("./site");
|
|
|
|
expect(docsAlternates(["agents"])).toEqual({
|
|
canonical: "https://www.multica.ai/docs/agents",
|
|
languages: {
|
|
en: "https://www.multica.ai/docs/agents",
|
|
zh: "https://www.multica.ai/docs/zh/agents",
|
|
fr: "https://www.multica.ai/docs/fr/agents",
|
|
"x-default": "https://www.multica.ai/docs/agents",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("keeps the locale root alternates limited to real localized MDX pages", async () => {
|
|
const { docsAlternates } = await import("./site");
|
|
|
|
expect(docsAlternates([])).toEqual({
|
|
canonical: "https://www.multica.ai/docs",
|
|
languages: {
|
|
en: "https://www.multica.ai/docs",
|
|
zh: "https://www.multica.ai/docs/zh",
|
|
"x-default": "https://www.multica.ai/docs",
|
|
},
|
|
});
|
|
});
|
|
});
|