Skip to content

Commit 37f2494

Browse files
committed
refactor: apply translations by result identity, drop keys slice in batch
- applyTranslations(parsedPo, results): lookup by result.msgctxt and result.msgid - clearFuzzyFromEntries(parsedPo, results): same; accept results with msgid/msgctxt - PoEntryOutput: add optional msgctxt for lookup - runTranslate: no batchKeys or keys.slice; pass batchResults only - tests: update po.test.ts for new applyTranslations/clearFuzzyFromEntries signatures Made-with: Cursor
1 parent f7e483f commit 37f2494

4 files changed

Lines changed: 29 additions & 32 deletions

File tree

src/cli/runTranslate.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export async function runTranslate(
6767
try {
6868
const poContent = fs.readFileSync(poFilePath, 'utf8');
6969
const parsedPo = parsePoContent(poContent);
70-
const { entries, keys } = getEntriesToTranslate(parsedPo, { includeFuzzy });
70+
const { entries } = getEntriesToTranslate(parsedPo, { includeFuzzy });
7171

7272
if (entries.length === 0) {
7373
console.log(`Nothing to translate in ${poFilePath}.`);
@@ -87,7 +87,6 @@ export async function runTranslate(
8787
}
8888
const options = { apiKey, sourceLanguage: sourceLang, formula, pluralSamples };
8989

90-
const allResults: Awaited<ReturnType<typeof translateStrings>> = [];
9190
for (let i = 0; i < entries.length; i += TRANSLATE_BATCH_SIZE) {
9291
const batch = entries.slice(i, i + TRANSLATE_BATCH_SIZE);
9392
const batchNum = Math.floor(i / TRANSLATE_BATCH_SIZE) + 1;
@@ -103,14 +102,13 @@ export async function runTranslate(
103102
console.log(` ${r.msgid_plural} (plural) => ${r.msgstr.join(' | ')}`);
104103
}
105104
}
106-
allResults.push(...batchResults);
105+
applyTranslations(parsedPo, batchResults);
106+
if (includeFuzzy) {
107+
clearFuzzyFromEntries(parsedPo, batchResults);
108+
}
109+
fs.writeFileSync(poFilePath, compilePo(parsedPo));
107110
}
108111

109-
applyTranslations(parsedPo, keys, allResults);
110-
if (includeFuzzy) {
111-
clearFuzzyFromEntries(parsedPo, keys);
112-
}
113-
fs.writeFileSync(poFilePath, compilePo(parsedPo), undefined);
114112
return 0;
115113
} catch (error) {
116114
const apiMessage = getApiErrorMessage(error);

src/po.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,18 @@ export function getEntriesToTranslate(
115115
/**
116116
* Applies translation results into the parsed PO (mutates parsedPo.translations).
117117
* Singular results become one-element msgstr; plural results stay as string[].
118+
* Lookup is by result.msgctxt (default '') and result.msgid.
118119
*/
119120
export function applyTranslations(
120121
parsedPo: GetTextTranslations,
121-
keys: PoEntryKey[],
122122
results: PoEntryOutput[],
123123
): void {
124-
for (let i = 0; i < keys.length; i++) {
125-
const key = keys[i];
126-
const result = results[i];
124+
for (const result of results) {
127125
if (result == null) continue;
128-
const contextEntries = parsedPo.translations[key.context];
126+
const context = result.msgctxt ?? '';
127+
const contextEntries = parsedPo.translations[context];
129128
if (contextEntries == null) continue;
130-
const entry = contextEntries[key.msgid];
129+
const entry = contextEntries[result.msgid];
131130
if (entry == null) continue;
132131

133132
if (typeof result.msgstr === 'string') {
@@ -139,14 +138,18 @@ export function applyTranslations(
139138
}
140139

141140
/**
142-
* Removes the "fuzzy" flag from entries at the given keys (mutates parsedPo.translations).
143-
* Used after applying new translations so fuzzy entries are no longer marked fuzzy.
141+
* Removes the "fuzzy" flag from entries corresponding to the given results (mutates parsedPo.translations).
142+
* Lookup is by result.msgctxt (default '') and result.msgid.
144143
*/
145-
export function clearFuzzyFromEntries(parsedPo: GetTextTranslations, keys: PoEntryKey[]): void {
146-
for (const key of keys) {
147-
const contextEntries = parsedPo.translations[key.context];
144+
export function clearFuzzyFromEntries(
145+
parsedPo: GetTextTranslations,
146+
results: Array<{ msgid: string; msgctxt?: string }>,
147+
): void {
148+
for (const result of results) {
149+
const context = result.msgctxt ?? '';
150+
const contextEntries = parsedPo.translations[context];
148151
if (contextEntries == null) continue;
149-
const entry = contextEntries[key.msgid];
152+
const entry = contextEntries[result.msgid];
150153
if (entry == null || !entry.comments?.flag) continue;
151154

152155
const newFlag = entry.comments.flag

src/translate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ export type PoEntryInput = {
246246

247247
/** .po-style entry output: same shape as input with msgstr filled (string for singular, string[] for plural). */
248248
export type PoEntryOutput =
249-
| { msgid: string; msgstr: string; msgid_plural?: undefined }
250-
| { msgid: string; msgid_plural: string; msgstr: string[] };
249+
| { msgid: string; msgstr: string; msgid_plural?: undefined; msgctxt?: string }
250+
| { msgid: string; msgid_plural: string; msgstr: string[]; msgctxt?: string };
251251

252252
export async function translateItems(
253253
items: TranslateItem[],

test/po.test.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,11 @@ msgstr[2] ""
152152
'utf8',
153153
),
154154
);
155-
const keys = [
156-
{ context: '', msgid: 'Hello' },
157-
{ context: '', msgid: 'Count' },
158-
];
159155
const results = [
160156
{ msgid: 'Hello', msgstr: 'Привіт' },
161157
{ msgid: 'Count', msgid_plural: 'Counts', msgstr: ['один', 'два', 'багато'] },
162158
];
163-
applyTranslations(parsed, keys, results);
159+
applyTranslations(parsed, results);
164160
expect(parsed.translations['']['Hello'].msgstr).toEqual(['Привіт']);
165161
expect(parsed.translations['']['Count'].msgstr).toEqual(['один', 'два', 'багато']);
166162
});
@@ -179,7 +175,7 @@ msgstr ""
179175
),
180176
);
181177
const before = parsed.translations['']['Hello'].msgstr.slice();
182-
applyTranslations(parsed, [{ context: '', msgid: 'Hello' }], []);
178+
applyTranslations(parsed, []);
183179
expect(parsed.translations['']['Hello'].msgstr).toEqual(before);
184180
});
185181

@@ -221,7 +217,7 @@ msgstr ""
221217
expect(keys).toHaveLength(1);
222218
expect(keys[0]).toEqual({ context: '', msgid: 'Hello' });
223219

224-
applyTranslations(parsed, keys, [{ msgid: 'Hello', msgstr: 'Привіт' }]);
220+
applyTranslations(parsed, [{ msgid: 'Hello', msgstr: 'Привіт', msgctxt: '' }]);
225221

226222
expect(parsed.translations['auth']['Hello'].msgstr).toEqual(['Вітаємо']);
227223
expect(parsed.translations['']['Hello'].msgstr).toEqual(['Привіт']);
@@ -276,9 +272,9 @@ msgstr "Старий переклад"
276272
const parsed = parsePoContent(tempPo.poContent);
277273
expect(isEntryFuzzy(parsed.translations['']['Hello'])).toBe(true);
278274

279-
const keys = [{ context: '', msgid: 'Hello' }];
280-
applyTranslations(parsed, keys, [{ msgid: 'Hello', msgstr: 'Новий переклад' }]);
281-
clearFuzzyFromEntries(parsed, keys);
275+
const results = [{ msgid: 'Hello', msgstr: 'Новий переклад' }];
276+
applyTranslations(parsed, results);
277+
clearFuzzyFromEntries(parsed, results);
282278

283279
expect(parsed.translations['']['Hello'].msgstr).toEqual(['Новий переклад']);
284280
expect(isEntryFuzzy(parsed.translations['']['Hello'])).toBe(false);

0 commit comments

Comments
 (0)