From 4ae3e331039cd659bc1bef9a7dc96524b173fcfe Mon Sep 17 00:00:00 2001 From: zipg Date: Fri, 7 Aug 2026 13:54:37 +0800 Subject: [PATCH] fix(i18n): parse imported locale sections in autofill --- .github/scripts/i18n-autofill.mjs | 12 ++++++++---- packages/app-tests/i18nAutofillParser.test.ts | 11 +++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 packages/app-tests/i18nAutofillParser.test.ts diff --git a/.github/scripts/i18n-autofill.mjs b/.github/scripts/i18n-autofill.mjs index 9ec2e4cde..ca6116f4f 100644 --- a/.github/scripts/i18n-autofill.mjs +++ b/.github/scripts/i18n-autofill.mjs @@ -201,9 +201,7 @@ function assertSamePlaceholders(key, source, translated, locale) { const sourcePlaceholders = placeholders(source); const translatedPlaceholders = placeholders(translated); if (sourcePlaceholders.join("\0") !== translatedPlaceholders.join("\0")) { - throw new Error( - `${locale}:${key} placeholder mismatch: expected [${sourcePlaceholders.join(", ")}], got [${translatedPlaceholders.join(", ")}]`, - ); + throw new Error(`${locale}:${key} placeholder mismatch: expected [${sourcePlaceholders.join(", ")}], got [${translatedPlaceholders.join(", ")}]`); } } @@ -362,7 +360,7 @@ function flattenNode(node, path, result) { const nextPath = [...path, property.key]; if (property.value.type === "object") { flattenNode(property.value, nextPath, result); - } else { + } else if (property.value.type === "string") { result.set(nextPath.join("."), property.value.value); } } @@ -416,6 +414,12 @@ class Parser { const start = this.index; const key = this.parseKey(); this.skipSpace(); + if (this.peek() === "," || this.peek() === "}") { + const hasComma = this.peek() === ","; + if (hasComma) this.index += 1; + properties.push({ key, start, end: this.index, hasComma, value: { type: "external" } }); + continue; + } this.expect(":"); this.skipSpace(); const value = this.parseValue(); diff --git a/packages/app-tests/i18nAutofillParser.test.ts b/packages/app-tests/i18nAutofillParser.test.ts new file mode 100644 index 000000000..12e0e81dc --- /dev/null +++ b/packages/app-tests/i18nAutofillParser.test.ts @@ -0,0 +1,11 @@ +import assert from "node:assert/strict"; +import { execFileSync } from "node:child_process"; +import { test } from "vitest"; + +test("i18n autofill parses locale roots with imported shorthand sections", () => { + const output = execFileSync(process.execPath, [".github/scripts/i18n-autofill.mjs", "--dry-run", "--base-ref", "HEAD"], { + encoding: "utf8", + }); + + assert.match(output, /No new zh-CN i18n keys compared with HEAD/); +});