fix(i18n): include concatenated Apple UI strings (#129882)

* fix(i18n): include concatenated Apple UI strings

* test(i18n): cover multiline Apple modifiers
This commit is contained in:
Vincent Koc
2026-08-26 13:24:48 +08:00
committed by GitHub
parent 3d37bb4cba
commit 263d2a2a91
2 changed files with 27 additions and 12 deletions
+6 -12
View File
@@ -25,16 +25,6 @@ const IOS_SOURCE_PREFIXES = [
SHARED_CHAT_UI_SOURCE_PREFIX,
"apps/shared/OpenClawKit/Sources/OpenClawKit/",
] as const;
const APPLE_CATALOG_KINDS = new Set([
"conditional-branch",
"ui-call",
"ui-call-multiline",
"ui-localized-call",
"ui-localized-call-multiline",
"ui-modifier",
"ui-named-argument",
"ui-named-argument-multiline",
]);
const IOS_CATALOG_EXCLUSIONS = new Set([
// Product names and preview-only single-character fixtures are intentionally verbatim.
"OpenClaw",
@@ -574,13 +564,17 @@ async function readOptionalFile(filePath: string): Promise<string | null> {
}
}
function isAppleCatalogKind(kind: string): boolean {
return kind === "conditional-branch" || kind.startsWith("ui-");
}
function isIosCatalogEntry(entry: NativeSourceEntry): boolean {
return (
entry.surface === "apple" &&
entry.sites.some(
(site) =>
IOS_SOURCE_PREFIXES.some((prefix) => site.path.startsWith(prefix)) &&
APPLE_CATALOG_KINDS.has(site.kind),
isAppleCatalogKind(site.kind),
) &&
(!entry.source.includes("\\(") || isInflectedCountSource(entry.source)) &&
!IOS_CATALOG_EXCLUSIONS.has(entry.source)
@@ -593,7 +587,7 @@ function isMacosCatalogEntry(entry: NativeSourceEntry): boolean {
entry.sites.some(
(site) =>
MACOS_SOURCE_PREFIXES.some((prefix) => site.path.startsWith(prefix)) &&
APPLE_CATALOG_KINDS.has(site.kind),
isAppleCatalogKind(site.kind),
) &&
!entry.source.includes("\\(") &&
!MACOS_CATALOG_EXCLUSIONS.has(entry.source)
+21
View File
@@ -222,6 +222,22 @@ describe("Apple app i18n catalogs", () => {
});
it("routes merged sites by coupled path and kind while preserving shipped translations", () => {
const coveredMacosEntries = [
{ kind: "ui-call-concatenated", source: "Call concatenated" },
{
kind: "ui-localized-call-concatenated",
source:
"Older generated approvals are inactive because they were not tied to a working directory. Manual rules are unchanged.",
},
{ kind: "ui-modifier-concatenated", source: "Modifier concatenated" },
{ kind: "ui-modifier-multiline", source: "Modifier multiline" },
{ kind: "ui-named-argument-concatenated", source: "Named argument concatenated" },
].map(({ kind, source }, index) => ({
id: `native.apple.concatenated.${index}`,
source,
surface: "apple",
sites: [{ kind, path: "apps/macos/Sources/OpenClaw/Example.swift" }],
}));
const inventory = {
version: 2,
entries: [
@@ -243,6 +259,7 @@ describe("Apple app i18n catalogs", () => {
{ kind: "ui-call", path: "outside/Example.swift" },
],
},
...coveredMacosEntries,
],
};
const existing = {
@@ -278,6 +295,10 @@ describe("Apple app i18n catalogs", () => {
});
expect(ios.catalog.strings?.["Do not catalog"]).toBeUndefined();
expect(macos.catalog.strings?.["Connect now"]).toBeDefined();
expect(Object.keys(macos.catalog.strings ?? {})).toEqual(
expect.arrayContaining(coveredMacosEntries.map((entry) => entry.source)),
);
expect(macos.catalog.strings?.["Do not catalog"]).toBeUndefined();
expect(ios.contradictions).toEqual([]);
});