UNPKG

json-translated-ai

Version:

AI-powered translation tool supporting OpenAI GPT, Anthropic Claude, and Google Gemini models

228 lines (206 loc) 7.26 kB
// Utility functions for translation insertion // These are the same functions from check-and-fix-translations.js but without ES module dependencies // Function to recursively get all keys(path) from an object export function getAllKeys(obj, prefix = '') { const keys = []; for (const key in obj) { const fullKey = prefix ? `${prefix}.${key}` : key; if (Array.isArray(obj[key])) { // Handle arrays - add keys for each element using bracket notation for (let i = 0; i < obj[key].length; i++) { const elementKey = `${fullKey}[${i}]`; const element = obj[key][i]; if (Array.isArray(element)) { // Handle nested arrays - recursively process with bracket notation // For nested arrays, we need to process each element with bracket notation for (let j = 0; j < element.length; j++) { const nestedElementKey = `${elementKey}[${j}]`; const nestedElement = element[j]; if (Array.isArray(nestedElement)) { // Handle deeply nested arrays keys.push(...getAllKeys(nestedElement, nestedElementKey)); } else if ( typeof nestedElement === 'object' && nestedElement !== null ) { // Handle objects within nested arrays keys.push(...getAllKeys(nestedElement, nestedElementKey)); } else { // Add individual nested array element keys keys.push(nestedElementKey); } } } else if (typeof element === 'object' && element !== null) { // Recursively process nested objects within arrays keys.push(...getAllKeys(element, elementKey)); } else { // Add individual array element keys keys.push(elementKey); } } } else if (typeof obj[key] === 'object' && obj[key] !== null) { // Handle nested objects keys.push(...getAllKeys(obj[key], fullKey)); } else { // Handle primitive values keys.push(fullKey); } } return keys; } // Function to get value from nested object using dot notation and bracket notation for arrays export function getNestedValue(obj, path) { // Parse the path to handle both dot notation and bracket notation const keys = []; let currentPath = path; while (currentPath.length > 0) { const bracketMatch = currentPath.match(/^([^[.]+)\[(\d+)\]/); if (bracketMatch) { // Found bracket notation like "array[0]" keys.push(bracketMatch[1]); // array name keys.push(bracketMatch[2]); // index currentPath = currentPath.substring(bracketMatch[0].length); if (currentPath.startsWith('.')) { currentPath = currentPath.substring(1); // Remove leading dot } } else if (currentPath.startsWith('[')) { // Handle consecutive bracket notation like "[1]" after "array[0]" const bracketIndexMatch = currentPath.match(/^\[(\d+)\]/); if (bracketIndexMatch) { keys.push(bracketIndexMatch[1]); // index currentPath = currentPath.substring(bracketIndexMatch[0].length); if (currentPath.startsWith('.')) { currentPath = currentPath.substring(1); // Remove leading dot } } else { // Invalid bracket syntax, treat as regular key keys.push(currentPath); break; } } else { // Handle dot notation const dotIndex = currentPath.indexOf('.'); if (dotIndex === -1) { keys.push(currentPath); break; } else { keys.push(currentPath.substring(0, dotIndex)); currentPath = currentPath.substring(dotIndex + 1); } } } return keys.reduce((current, key) => { // Check if this is a numeric key (array index) const isNumericKey = /^\d+$/.test(key); if (isNumericKey && Array.isArray(current)) { // Handle array indices like "0", "1", etc. const index = parseInt(key); return current?.[index]; } return current?.[key]; }, obj); } // Function to set value in nested object using dot notation and bracket notation for arrays export function setNestedValue(obj, path, value) { // Parse the path to handle both dot notation and bracket notation const keys = []; let currentPath = path; while (currentPath.length > 0) { const bracketMatch = currentPath.match(/^([^[.]+)\[(\d+)\]/); if (bracketMatch) { // Found bracket notation like "array[0]" keys.push(bracketMatch[1]); // array name keys.push(bracketMatch[2]); // index currentPath = currentPath.substring(bracketMatch[0].length); if (currentPath.startsWith('.')) { currentPath = currentPath.substring(1); // Remove leading dot } } else { // Handle dot notation const dotIndex = currentPath.indexOf('.'); if (dotIndex === -1) { keys.push(currentPath); break; } else { keys.push(currentPath.substring(0, dotIndex)); currentPath = currentPath.substring(dotIndex + 1); } } } let current = obj; let parents = []; let parentKeys = []; for (let i = 0; i < keys.length; i++) { const key = keys[i]; const isNumericKey = /^\d+$/.test(key); const nextKey = keys[i + 1]; const isNextNumeric = /^\d+$/.test(nextKey); // Track parent and key for possible array conversion if (i > 0) { parents[i] = current; parentKeys[i] = keys[i - 1]; } if (i === keys.length - 1) { // Last key, set the value if (isNumericKey) { if (!Array.isArray(current)) { // Convert parent property to array if (i === 0) { // At root obj = []; current = obj; } else { parents[i][parentKeys[i]] = []; current = parents[i][parentKeys[i]]; } } current[key] = value; } else { current[key] = value; } } else { // Not last key, prepare the next level if (isNumericKey) { if (!Array.isArray(current[key])) { current[key] = []; } current = current[key]; } else { if (current[key] === undefined) { current[key] = isNextNumeric ? [] : {}; } current = current[key]; } } } } // Function to check if a key exists in the target object export function keyExists(obj, path) { return getNestedValue(obj, path) !== undefined; } // Function to get missing keys export function getMissingKeys(template, target) { const templateKeys = getAllKeys(template); const missingKeys = []; for (const key of templateKeys) { if (!keyExists(target, key)) { missingKeys.push(key); } } return missingKeys; } // Function to get extra keys (keys in target but not in template) export function getExtraKeys(template, target) { const targetKeys = getAllKeys(target); const extraKeys = []; for (const key of targetKeys) { if (!keyExists(template, key)) { extraKeys.push(key); } } return extraKeys; } // Function to generate a random delay between min and max values export function getRandomDelay(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }