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() {
try {
const manager = new LocaleManager();
await manager.updateAllGeneratedTranslations();
const files = manager.translationFiles;
let hasMissingTranslations = false;

View File

@@ -4,7 +4,7 @@ import { TranslationFile, TranslationLocale } from "./types";
/** Root path for all translation files */
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"];
/** base locale */

View File

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

View File

@@ -1,4 +1,3 @@
// jsonService.ts
import _ from "lodash";
export interface NestedTranslations {
@@ -13,19 +12,19 @@ export class JsonService {
* @returns A flattened object with dot-notation keys
*/
flatten(obj: NestedTranslations, prefix = ""): Record<string, string> {
return Object.keys(obj).reduce(
(acc, key) => {
const result: Record<string, string> = {};
for (const [key, value] of Object.entries(obj)) {
const newKey = prefix ? `${prefix}.${key}` : key;
if (_.isPlainObject(obj[key])) {
Object.assign(acc, this.flatten(obj[key] as NestedTranslations, newKey));
if (typeof value === "object" && value !== null) {
Object.assign(result, this.flatten(value as NestedTranslations, newKey));
} else {
// Handle empty strings explicitly
acc[newKey] = obj[key] === "" ? "" : (obj[key] as string);
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 path from "path";
import { TRANSLATION_ROOT_PATH, TRANSLATION_FILES, BASE_LOCALE } from "./constants";
@@ -30,7 +29,6 @@ export class LocaleManager {
constructor() {
this.rootPath = TRANSLATION_ROOT_PATH;
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[];
}
/**
* 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
* @param locale The locale identifier (e.g., 'en', 'fr')