diff --git a/web/i18n-config/auto-gen-i18n.js b/web/i18n-config/auto-gen-i18n.js index 556fd6376e..f84a2388af 100644 --- a/web/i18n-config/auto-gen-i18n.js +++ b/web/i18n-config/auto-gen-i18n.js @@ -162,89 +162,24 @@ async function translateText(source, toLanguage) { } } -async function translateMissingKeyDeeply(sourceObj, targetObject, toLanguage) { +async function translateMissingKeys(sourceObj, targetObject, toLanguage) { const skippedKeys = [] const translatedKeys = [] - const entries = Object.keys(sourceObj) - - const processArray = async (sourceArray, targetArray, parentKey) => { - for (let i = 0; i < sourceArray.length; i++) { - const item = sourceArray[i] - const pathKey = `${parentKey}[${i}]` - - const existingTarget = targetArray[i] - - if (typeof item === 'object' && item !== null) { - const targetChild = (Array.isArray(existingTarget) || typeof existingTarget === 'object') ? existingTarget : (Array.isArray(item) ? [] : {}) - const childResult = await translateMissingKeyDeeply(item, targetChild, toLanguage) - targetArray[i] = targetChild - skippedKeys.push(...childResult.skipped.map(k => `${pathKey}.${k}`)) - translatedKeys.push(...childResult.translated.map(k => `${pathKey}.${k}`)) - } - else { - if (existingTarget !== undefined) - continue - - const translationResult = await translateText(item, toLanguage) - targetArray[i] = translationResult.value ?? '' - if (translationResult.skipped) - skippedKeys.push(`${pathKey}: ${item}`) - else - translatedKeys.push(pathKey) - } - } - } - - for (const key of entries) { + for (const key of Object.keys(sourceObj)) { const sourceValue = sourceObj[key] const targetValue = targetObject[key] - if (targetValue === undefined) { - if (Array.isArray(sourceValue)) { - const translatedArray = [] - await processArray(sourceValue, translatedArray, key) - targetObject[key] = translatedArray - } - else if (typeof sourceValue === 'object' && sourceValue !== null) { - targetObject[key] = {} - const result = await translateMissingKeyDeeply(sourceValue, targetObject[key], toLanguage) - skippedKeys.push(...result.skipped.map(k => `${key}.${k}`)) - translatedKeys.push(...result.translated.map(k => `${key}.${k}`)) - } - else { - const translationResult = await translateText(sourceValue, toLanguage) - targetObject[key] = translationResult.value ?? '' - if (translationResult.skipped) - skippedKeys.push(`${key}: ${sourceValue}`) - else - translatedKeys.push(key) - } - } - else if (Array.isArray(sourceValue)) { - const targetArray = Array.isArray(targetValue) ? targetValue : [] - await processArray(sourceValue, targetArray, key) - targetObject[key] = targetArray - } - else if (typeof sourceValue === 'object' && sourceValue !== null) { - const targetChild = targetValue && typeof targetValue === 'object' ? targetValue : {} - targetObject[key] = targetChild - const result = await translateMissingKeyDeeply(sourceValue, targetChild, toLanguage) - skippedKeys.push(...result.skipped.map(k => `${key}.${k}`)) - translatedKeys.push(...result.translated.map(k => `${key}.${k}`)) - } - else { - // Overwrite when type is different or value is missing to keep structure in sync - const shouldUpdate = typeof targetValue !== typeof sourceValue || targetValue === undefined || targetValue === null - if (shouldUpdate) { - const translationResult = await translateText(sourceValue, toLanguage) - targetObject[key] = translationResult.value ?? '' - if (translationResult.skipped) - skippedKeys.push(`${key}: ${sourceValue}`) - else - translatedKeys.push(key) - } - } + // Skip if target already has this key + if (targetValue !== undefined) + continue + + const translationResult = await translateText(sourceValue, toLanguage) + targetObject[key] = translationResult.value ?? '' + if (translationResult.skipped) + skippedKeys.push(`${key}: ${sourceValue}`) + else + translatedKeys.push(key) } return { skipped: skippedKeys, translated: translatedKeys } @@ -268,7 +203,7 @@ async function autoGenTrans(fileName, toGenLanguage, isDryRun = false) { } console.log(`\nšŸŒ Processing ${fileName} for ${toGenLanguage}...`) - const result = await translateMissingKeyDeeply(fullKeyContent, toGenOutPut, toGenLanguage) + const result = await translateMissingKeys(fullKeyContent, toGenOutPut, toGenLanguage) // Generate summary report console.log(`\nšŸ“Š Translation Summary for ${fileName} -> ${toGenLanguage}:`) diff --git a/web/i18n-config/check-i18n.js b/web/i18n-config/check-i18n.js index 4ca24a0d19..5b6efec385 100644 --- a/web/i18n-config/check-i18n.js +++ b/web/i18n-config/check-i18n.js @@ -134,24 +134,8 @@ async function getKeysFromLanguage(language) { return } - const nestedKeys = [] - const iterateKeys = (obj, prefix = '') => { - for (const key in obj) { - const nestedKey = prefix ? `${prefix}.${key}` : key - if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) { - // This is an object (but not array), recurse into it but don't add it as a key - iterateKeys(obj[key], nestedKey) - } - else { - // This is a leaf node (string, number, boolean, array, etc.), add it as a key - nestedKeys.push(nestedKey) - } - } - } - iterateKeys(translationObj) - - // Fixed: accumulate keys instead of overwriting - const fileKeys = nestedKeys.map(key => `${camelCaseFileName}.${key}`) + // Flat structure: just get all keys directly + const fileKeys = Object.keys(translationObj).map(key => `${camelCaseFileName}.${key}`) allKeys.push(...fileKeys) } catch (error) { @@ -190,35 +174,15 @@ async function removeExtraKeysFromFile(language, fileName, extraKeys) { let modified = false - // Remove each extra key + // Remove each extra key (flat structure - direct property deletion) for (const keyToRemove of fileSpecificKeys) { - const keyParts = keyToRemove.split('.') - let current = translationObj - - // Navigate to the parent of the key to remove - for (let i = 0; i < keyParts.length; i++) { - const part = keyParts[i] - if (i === keyParts.length - 1) { - // This is the key to remove - if (current && typeof current === 'object' && part in current) { - delete current[part] - console.log(`šŸ—‘ļø Removed key: ${keyToRemove}`) - modified = true - } - else { - console.log(`āš ļø Could not find key: ${keyToRemove}`) - } - } - else { - // Navigate deeper - if (current && typeof current === 'object' && part in current) { - current = current[part] - } - else { - console.log(`āš ļø Could not find key path: ${keyToRemove}`) - break - } - } + if (keyToRemove in translationObj) { + delete translationObj[keyToRemove] + console.log(`šŸ—‘ļø Removed key: ${keyToRemove}`) + modified = true + } + else { + console.log(`āš ļø Could not find key: ${keyToRemove}`) } }