All files / scripts/locale check-translations.ts

100% Statements 21/21
100% Branches 6/6
100% Functions 6/6
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 831x 1x                                                                         1x 1x   1x 1x 1x   1x 4x   4x 1624x   28421x       4x 2x   2x 150x     2850x   2247x   150x                 1x           1x  
import { BASE_LOCALE } from "./constants";
import { LocaleManager } from "./manager";
import { TranslationRow, TranslationStatus } from "./types";
 
/**
 * Represents a missing translation entry.
 * Contains information about which key is missing in which locales(eg- [id, cs, de]).
 */
export interface MissingTranslation {
  key: string;
  file: string;
  missingLocales: string[];
}
 
/**
 * Result object returned by the checkMissingTranslations function.
 * Contains information about whether there are any missing translations
 * and details about each missing translation.
 */
export interface CheckTranslationsResult {
  /** Flag indicating if any translations are missing */
  hasMissingTranslations: boolean;
  /** Array of missing translation details */
  missingTranslations: MissingTranslation[];
}
 
/**
 * Checks for missing translations across all locale files.
 *
 * This function:
 * 1. Updates all generated translations
 * 2. Iterates through each translation file
 * 3. Identifies missing translations by comparing against the base locale
 * 4. Collects details about missing translations including which keys are missing in which locales
 *
 * @returns {Promise<CheckTranslationsResult>} Object containing missing translation information
 */
async function checkMissingTranslations(): Promise<CheckTranslationsResult> {
  const manager = new LocaleManager();
  await manager.updateAllGeneratedTranslations();
 
  const files = manager.translationFiles;
  let hasMissingTranslations = false;
  const missingTranslations: MissingTranslation[] = [];
 
  for (const file of files) {
    const rows = await manager.generateTranslationRows(file);
 
    const missingRows = rows.filter((row: TranslationRow) =>
      Object.entries(row.translations).some(
        ([locale, translation]: [string, TranslationStatus]) =>
          locale !== BASE_LOCALE && translation.status === "missing"
      )
    );
 
    if (missingRows.length > 0) {
      hasMissingTranslations = true;
 
      missingRows.forEach((row: TranslationRow) => {
        const missingLocales = Object.entries(row.translations)
          .filter(
            ([locale, translation]: [string, TranslationStatus]) =>
              locale !== BASE_LOCALE && translation.status === "missing"
          )
          .map(([locale]) => locale);
 
        missingTranslations.push({
          key: row.key,
          file,
          missingLocales,
        });
      });
    }
  }
 
  return {
    hasMissingTranslations,
    missingTranslations,
  };
}
 
export { checkMissingTranslations };