Skip to content

Commit 891b910

Browse files
committed
Fix plural forms structure in POEditor scripts
- Add restructurePluralForms() to downloader: converts POEditor export format to correct structure - Add defensive restructurePluralForms() to uploader: handles malformed files automatically - Ensures batch files are saved with proper plural nesting: { term: { one: ..., other: ... } } - Fixes issue where POEditor's export returns { one: { terms }, other: { terms } } format
1 parent 1e98abb commit 891b910

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

locale/scripts/poeditor-downloader.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,39 @@ async function fetchUntranslatedTerms(poEditorLocale) {
139139
});
140140
}
141141

142+
/**
143+
* Restructure POEditor export from malformed to correct format for upload.
144+
* POEditor returns: { "one": { term1: "...", term2: "..." }, "other": { ... } }
145+
* We need: { "term1": { "one": "...", "other": "..." }, "term2": { ... } }
146+
*/
147+
function restructurePluralForms(data) {
148+
if (!data.one && !data.other) return data;
149+
if (typeof data.one === 'object' && typeof data.other === 'object') {
150+
const restructured = {};
151+
for (const [key, value] of Object.entries(data)) {
152+
if (key !== 'one' && key !== 'other' && typeof value === 'string') {
153+
restructured[key] = value;
154+
}
155+
}
156+
const termKeys = new Set([...Object.keys(data.one || {}), ...Object.keys(data.other || {})]);
157+
for (const term of termKeys) {
158+
const pluralForms = {};
159+
if (data.one && data.one[term]) pluralForms.one = data.one[term];
160+
if (data.other && data.other[term]) pluralForms.other = data.other[term];
161+
if (Object.keys(pluralForms).length > 0) restructured[term] = pluralForms;
162+
}
163+
return restructured;
164+
}
165+
return data;
166+
}
167+
142168
/**
143169
* Save missing terms in batched JSON files under MISSING_OUTPUT_DIR/{poEditorCode}/
144170
* Returns array of written file paths.
145171
*/
146172
function saveBatchedMissingTerms(poEditorCode, missingTerms) {
173+
missingTerms = restructurePluralForms(missingTerms);
174+
147175
const localeOutDir = path.join(MISSING_OUTPUT_DIR, poEditorCode);
148176

149177
if (!fs.existsSync(localeOutDir)) {

locale/scripts/poeditor-upload-missing.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,33 @@ function loadEnglishOkAllowlist() {
188188
}
189189
}
190190

191+
// ── Plural form restructuring ───────────────────────────────────────────────
192+
193+
/**
194+
* Defensive restructure for malformed plural forms from POEditor export.
195+
* If batch file has top-level "one"/"other", fixes to proper nesting.
196+
*/
197+
function restructurePluralForms(data) {
198+
if (!data.one && !data.other) return data;
199+
if (typeof data.one === 'object' && typeof data.other === 'object') {
200+
const restructured = {};
201+
for (const [key, value] of Object.entries(data)) {
202+
if (key !== 'one' && key !== 'other' && typeof value === 'string') {
203+
restructured[key] = value;
204+
}
205+
}
206+
const termKeys = new Set([...Object.keys(data.one || {}), ...Object.keys(data.other || {})]);
207+
for (const term of termKeys) {
208+
const pluralForms = {};
209+
if (data.one && data.one[term]) pluralForms.one = data.one[term];
210+
if (data.other && data.other[term]) pluralForms.other = data.other[term];
211+
if (Object.keys(pluralForms).length > 0) restructured[term] = pluralForms;
212+
}
213+
return restructured;
214+
}
215+
return data;
216+
}
217+
191218
// ── Term analysis ────────────────────────────────────────────────────────────
192219

193220
/**
@@ -229,7 +256,8 @@ function isNotIdenticalToKey(termKey, value) {
229256
* @param {Set<string>} [englishOkSet] - optional set of terms safe to upload as-is
230257
*/
231258
function analyzeFile(filePath, englishOkSet = new Set()) {
232-
const raw = JSON.parse(fs.readFileSync(filePath, 'utf8'));
259+
let raw = JSON.parse(fs.readFileSync(filePath, 'utf8'));
260+
raw = restructurePluralForms(raw); // Defensive: fix malformed plural structure if present
233261
const localizedTerms = {};
234262
const suspectTerms = {};
235263
const emptyTerms = {};

0 commit comments

Comments
 (0)