Merge branch 'chore/i18n-dev-tooling' into chore/i18n-dev-tooling-tsx-normalize

This commit is contained in:
Jayash Tripathy
2025-09-15 00:43:42 +05:30
5 changed files with 25 additions and 18 deletions

View File

@@ -8,6 +8,8 @@ import { TranslationRow, TranslationStatus } from "./locale/types";
async function checkMissingTranslations() { async function checkMissingTranslations() {
try { try {
const manager = new LocaleManager(); const manager = new LocaleManager();
await manager.updateAllGeneratedTranslations();
const files = manager.translationFiles; const files = manager.translationFiles;
let hasMissingTranslations = false; let hasMissingTranslations = false;

View File

@@ -4,7 +4,7 @@ import { TranslationFile, TranslationLocale } from "./types";
/** Root path for all translation files */ /** Root path for all translation files */
export const TRANSLATION_ROOT_PATH = path.join(__dirname, "../../src/locales"); export const TRANSLATION_ROOT_PATH = path.join(__dirname, "../../src/locales");
/** Comma-separated list of translation file categories */ /** list of translation file categories */
export const TRANSLATION_FILES: TranslationFile[] = ["translations", "accessibility", "editor", "core"]; export const TRANSLATION_FILES: TranslationFile[] = ["translations", "accessibility", "editor", "core"];
/** base locale */ /** base locale */

View File

@@ -1,4 +1,3 @@
// fileService.ts
import { promises as fs } from "fs"; import { promises as fs } from "fs";
export class FileService { export class FileService {

View File

@@ -1,4 +1,3 @@
// jsonService.ts
import _ from "lodash"; import _ from "lodash";
export interface NestedTranslations { export interface NestedTranslations {
@@ -13,19 +12,19 @@ export class JsonService {
* @returns A flattened object with dot-notation keys * @returns A flattened object with dot-notation keys
*/ */
flatten(obj: NestedTranslations, prefix = ""): Record<string, string> { flatten(obj: NestedTranslations, prefix = ""): Record<string, string> {
return Object.keys(obj).reduce( const result: Record<string, string> = {};
(acc, key) => {
const newKey = prefix ? `${prefix}.${key}` : key; for (const [key, value] of Object.entries(obj)) {
if (_.isPlainObject(obj[key])) { const newKey = prefix ? `${prefix}.${key}` : key;
Object.assign(acc, this.flatten(obj[key] as NestedTranslations, newKey));
} else { if (typeof value === "object" && value !== null) {
// Handle empty strings explicitly Object.assign(result, this.flatten(value as NestedTranslations, newKey));
acc[newKey] = obj[key] === "" ? "" : (obj[key] as string); } else {
} result[newKey] = value === "" ? "" : (value as string);
return acc; }
}, }
{} as Record<string, string>
); return result;
} }
/** /**

View File

@@ -1,4 +1,3 @@
// translationManager.ts
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import path from "path"; import path from "path";
import { TRANSLATION_ROOT_PATH, TRANSLATION_FILES, BASE_LOCALE } from "./constants"; import { TRANSLATION_ROOT_PATH, TRANSLATION_FILES, BASE_LOCALE } from "./constants";
@@ -30,7 +29,6 @@ export class LocaleManager {
constructor() { constructor() {
this.rootPath = TRANSLATION_ROOT_PATH; this.rootPath = TRANSLATION_ROOT_PATH;
this.translationFiles = TRANSLATION_FILES; this.translationFiles = TRANSLATION_FILES;
this.translationFiles.forEach((f) => this.updateGeneratedTranslations(f));
} }
/** /**
@@ -43,6 +41,15 @@ export class LocaleManager {
return files.filter((f) => isValidLocaleDirectory(f)) as TranslationLocale[]; return files.filter((f) => isValidLocaleDirectory(f)) as TranslationLocale[];
} }
/**
* Update all the generated translation files in the memory
*/
async updateAllGeneratedTranslations(): Promise<void> {
for (const file of this.translationFiles) {
await this.updateGeneratedTranslations(file);
}
}
/** /**
* Constructs the full file path for a translation file * Constructs the full file path for a translation file
* @param locale The locale identifier (e.g., 'en', 'fr') * @param locale The locale identifier (e.g., 'en', 'fr')