Skip to content

Commit 014afd2

Browse files
committed
fix: normalize en sources before manifest hashing and filter chunk response ids
1 parent 4350fea commit 014afd2

17 files changed

Lines changed: 89 additions & 106 deletions

.github/workflows/i18n-update-custom-nodes.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
run: |
8181
LOCALE_DIR=ComfyUI/custom_nodes/${{ inputs.repository }}/locales/
8282
install -d "$LOCALE_DIR"
83-
cp -rf ComfyUI_frontend/temp/diff/* "$LOCALE_DIR"
83+
cp -rf temp/diff/* "$LOCALE_DIR"
8484
8585
# Git ops for pushing changes and creating PR
8686
- name: Check and create fork of custom node repository

scripts/i18n/translate.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,13 @@ export async function translateLocaleItems(
204204
const responses = await mapWithConcurrency(
205205
chunks,
206206
config.requestConcurrency,
207-
(chunk) => translateBatch(locale, chunk)
208-
)
209-
const translated = new Map(
210-
responses.flatMap((response) => Object.entries(response))
207+
async (chunk) => {
208+
const requested = new Set(chunk.map((item) => item.id))
209+
const response = await translateBatch(locale, chunk)
210+
return Object.entries(response).filter(([id]) => requested.has(id))
211+
}
211212
)
213+
const translated = new Map(responses.flat())
212214

213215
const failed: TranslationItem[] = []
214216
for (const item of remaining) {

scripts/i18n/update-locales.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,30 @@ describe('translateLocaleItems', () => {
185185
).rejects.toThrow(/failed for 1 strings/)
186186
})
187187

188+
it('ignores response ids that were not requested in the same chunk', async () => {
189+
const threeItems: TranslationItem[] = ['1', '2', '3'].map((id) => ({
190+
id,
191+
context: `main.json: key${id}`,
192+
source: `Source ${id}`,
193+
preserve: []
194+
}))
195+
const responses: Array<Record<string, string>> = [
196+
{ '1': 'ok1', '2': 'ok2', '3': 'WRONG' },
197+
{},
198+
{ '3': 'ok3' }
199+
]
200+
let call = 0
201+
const crossTalking: TranslateBatch = () =>
202+
Promise.resolve(responses[call++] ?? {})
203+
const translations = await translateLocaleItems(
204+
locale,
205+
threeItems,
206+
crossTalking,
207+
translationConfig
208+
)
209+
expect(translations.get('3')).toBe('ok3')
210+
})
211+
188212
it('sends a retry note naming the violation on later rounds', async () => {
189213
const seenNotes: Array<string | undefined> = []
190214
const flaky: TranslateBatch = (_batchLocale, batch) => {

scripts/i18n/update-locales.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,14 @@ async function run(argv: readonly string[]): Promise<void> {
325325
const filenames = sourceFiles(entryDir)
326326

327327
const plans: SourcePlan[] = filenames.map((filename) => {
328-
const source = readLocale(join(entryDir, filename))
328+
const entryFile = join(entryDir, filename)
329+
const raw = readFileSync(entryFile, 'utf8')
330+
const source = parseLocale(raw, filename)
331+
// The manifest records git blob hashes of the entry files, so their bytes
332+
// must match what gets committed: normalize to the same serialization
333+
// writeLocale produces (collect-i18n omits the trailing newline oxfmt adds)
334+
const canonical = serializeLocale(source)
335+
if (!check && raw !== canonical) writeFileSync(entryFile, canonical)
329336
const hash = manifest.files[filename]
330337
const previous = hash ? readManifestSource(repoRoot, filename, hash) : {}
331338
const changes = diffLocaleSources(previous, source)

src/locales/ar/nodeDefs.json

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@
889889
"tooltip": "معرّف أصل Seedance لاستخدامه كالإطار الأخير. لا يمكن استخدامه مع إدخال صورة الإطار الأخير."
890890
},
891891
"model": {
892-
"name": "النموذج",
893-
"tooltip": "Seedance 2.0 لأعلى جودة؛ Seedance 2.0 Fast لتحسين السرعة."
892+
"name": "النموذج"
894893
},
895894
"model_duration": {
896895
"name": "المدة"
@@ -930,8 +929,7 @@
930929
"name": "التحكم بعد الإنشاء"
931930
},
932931
"model": {
933-
"name": "النموذج",
934-
"tooltip": "Seedance 2.0 لأعلى جودة؛ Seedance 2.0 Fast لتحسين السرعة."
932+
"name": "النموذج"
935933
},
936934
"model_auto_downscale": {
937935
"name": "التقليل التلقائي للحجم"
@@ -983,8 +981,7 @@
983981
"name": "التحكم بعد الإنشاء"
984982
},
985983
"model": {
986-
"name": "النموذج",
987-
"tooltip": "Seedance 2.0 لأعلى جودة؛ Seedance 2.0 Fast لتحسين السرعة."
984+
"name": "النموذج"
988985
},
989986
"model_duration": {
990987
"name": "المدة"
@@ -5967,8 +5964,7 @@
59675964
"tooltip": "وصف نصي للفيديو المطلوب. اختياري لـ grok-imagine-video-1.5 عند توفير صورة إدخال."
59685965
},
59695966
"resolution": {
5970-
"name": "الدقة",
5971-
"tooltip": "دقة الفيديو الناتج."
5967+
"name": "الدقة"
59725968
},
59735969
"seed": {
59745970
"name": "البذرة",

src/locales/es/nodeDefs.json

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@
889889
"tooltip": "ID de asset de Seedance para usar como último fotograma. Es excluyente con la entrada de imagen last_frame."
890890
},
891891
"model": {
892-
"name": "modelo",
893-
"tooltip": "Seedance 2.0 para máxima calidad; Seedance 2.0 Fast para optimización de velocidad."
892+
"name": "modelo"
894893
},
895894
"model_duration": {
896895
"name": "duración"
@@ -930,8 +929,7 @@
930929
"name": "control después de generar"
931930
},
932931
"model": {
933-
"name": "modelo",
934-
"tooltip": "Seedance 2.0 para máxima calidad; Seedance 2.0 Fast para optimización de velocidad."
932+
"name": "modelo"
935933
},
936934
"model_auto_downscale": {
937935
"name": "auto_downscale"
@@ -983,8 +981,7 @@
983981
"name": "control después de generar"
984982
},
985983
"model": {
986-
"name": "modelo",
987-
"tooltip": "Seedance 2.0 para máxima calidad; Seedance 2.0 Fast para optimización de velocidad."
984+
"name": "modelo"
988985
},
989986
"model_duration": {
990987
"name": "duración"
@@ -5967,8 +5964,7 @@
59675964
"tooltip": "Descripción textual del video deseado. Es opcional para grok-imagine-video-1.5 cuando se proporciona una imagen de entrada."
59685965
},
59695966
"resolution": {
5970-
"name": "resolución",
5971-
"tooltip": "La resolución del video de salida."
5967+
"name": "resolución"
59725968
},
59735969
"seed": {
59745970
"name": "semilla",

src/locales/fa/nodeDefs.json

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@
889889
"tooltip": "شناسه asset_id مربوط به Seedance برای استفاده به عنوان آخرین فریم. با ورودی تصویر last_frame ناسازگار است."
890890
},
891891
"model": {
892-
"name": "مدل",
893-
"tooltip": "Seedance 2.0 برای بالاترین کیفیت؛ Seedance 2.0 Fast برای بهینه‌سازی سرعت."
892+
"name": "مدل"
894893
},
895894
"model_duration": {
896895
"name": "مدت زمان"
@@ -930,8 +929,7 @@
930929
"name": "کنترل پس از تولید"
931930
},
932931
"model": {
933-
"name": "مدل",
934-
"tooltip": "Seedance 2.0 برای بالاترین کیفیت؛ Seedance 2.0 Fast برای بهینه‌سازی سرعت."
932+
"name": "مدل"
935933
},
936934
"model_auto_downscale": {
937935
"name": "auto_downscale"
@@ -983,8 +981,7 @@
983981
"name": "کنترل پس از تولید"
984982
},
985983
"model": {
986-
"name": "مدل",
987-
"tooltip": "Seedance 2.0 برای بالاترین کیفیت؛ Seedance 2.0 Fast برای بهینه‌سازی سرعت."
984+
"name": "مدل"
988985
},
989986
"model_duration": {
990987
"name": "مدت زمان"
@@ -5967,8 +5964,7 @@
59675964
"tooltip": "توضیح متنی ویدیوی موردنظر. هنگامی که یک تصویر ورودی ارائه شده باشد، برای grok-imagine-video-1.5 اختیاری است."
59685965
},
59695966
"resolution": {
5970-
"name": "وضوح",
5971-
"tooltip": "وضوح ویدیوی خروجی."
5967+
"name": "وضوح"
59725968
},
59735969
"seed": {
59745970
"name": "بذر",

src/locales/fr/nodeDefs.json

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@
889889
"tooltip": "ID d’actif Seedance à utiliser comme dernière image. Mutuellement exclusif avec l’entrée image last_frame."
890890
},
891891
"model": {
892-
"name": "modèle",
893-
"tooltip": "Seedance 2.0 pour une qualité maximale ; Seedance 2.0 Fast pour une optimisation de la vitesse."
892+
"name": "modèle"
894893
},
895894
"model_duration": {
896895
"name": "durée"
@@ -930,8 +929,7 @@
930929
"name": "contrôle après génération"
931930
},
932931
"model": {
933-
"name": "modèle",
934-
"tooltip": "Seedance 2.0 pour une qualité maximale ; Seedance 2.0 Fast pour une optimisation de la vitesse."
932+
"name": "modèle"
935933
},
936934
"model_auto_downscale": {
937935
"name": "auto_downscale"
@@ -983,8 +981,7 @@
983981
"name": "contrôle après génération"
984982
},
985983
"model": {
986-
"name": "modèle",
987-
"tooltip": "Seedance 2.0 pour une qualité maximale ; Seedance 2.0 Fast pour une optimisation de la vitesse."
984+
"name": "modèle"
988985
},
989986
"model_duration": {
990987
"name": "durée"
@@ -5967,8 +5964,7 @@
59675964
"tooltip": "Description textuelle de la vidéo souhaitée. Facultative pour grok-imagine-video-1.5 lorsqu’une image d’entrée est fournie."
59685965
},
59695966
"resolution": {
5970-
"name": "résolution",
5971-
"tooltip": "La résolution de la vidéo générée."
5967+
"name": "résolution"
59725968
},
59735969
"seed": {
59745970
"name": "graine",

src/locales/he/nodeDefs.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@
889889
"tooltip": "Seedance asset_id לשימוש כפריים האחרון. לא ניתן לשלב עם קלט תמונת last_frame."
890890
},
891891
"model": {
892-
"name": "model",
893-
"tooltip": "Seedance 2.0 לאיכות מרבית; Fast לאופטימיזציית מהירות; Mini לדור מהיר וזול במיוחד."
892+
"name": "model"
894893
},
895894
"model_duration": {
896895
"name": "duration"
@@ -930,8 +929,7 @@
930929
"name": "control after generate"
931930
},
932931
"model": {
933-
"name": "model",
934-
"tooltip": "Seedance 2.0 לאיכות מרבית; Fast לאופטימיזציית מהירות; Mini לדור מהיר וזול במיוחד."
932+
"name": "model"
935933
},
936934
"model_auto_downscale": {
937935
"name": "auto_downscale"
@@ -983,8 +981,7 @@
983981
"name": "שליטה לאחר יצירה"
984982
},
985983
"model": {
986-
"name": "מודל",
987-
"tooltip": "Seedance 2.0 לאיכות מרבית; Fast לאופטימיזציית מהירות; Mini לדור המהיר והחסכוני ביותר."
984+
"name": "מודל"
988985
},
989986
"model_duration": {
990987
"name": "משך"

src/locales/it/nodeDefs.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@
889889
"tooltip": "Seedance asset_id da usare come ultimo frame. Esclusivo rispetto all'input immagine dell'ultimo frame."
890890
},
891891
"model": {
892-
"name": "modello",
893-
"tooltip": "Seedance 2.0 per la massima qualità; Fast per ottimizzare la velocità; Mini per la generazione più veloce e a basso costo."
892+
"name": "modello"
894893
},
895894
"model_duration": {
896895
"name": "durata"
@@ -930,8 +929,7 @@
930929
"name": "controllo dopo la generazione"
931930
},
932931
"model": {
933-
"name": "modello",
934-
"tooltip": "Seedance 2.0 per la massima qualità; Fast per ottimizzare la velocità; Mini per la generazione più veloce e a basso costo."
932+
"name": "modello"
935933
},
936934
"model_auto_downscale": {
937935
"name": "ridimensionamento automatico in basso"
@@ -983,8 +981,7 @@
983981
"name": "controllo dopo la generazione"
984982
},
985983
"model": {
986-
"name": "modello",
987-
"tooltip": "Seedance 2.0 per la massima qualità; Fast per ottimizzare la velocità; Mini per la generazione più veloce e a basso costo."
984+
"name": "modello"
988985
},
989986
"model_duration": {
990987
"name": "durata"

0 commit comments

Comments
 (0)