mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 11:54:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			158 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* eslint-disable node/no-extraneous-require */
 | 
						|
 | 
						|
'use strict';
 | 
						|
 | 
						|
const path = require('path');
 | 
						|
const chalk = require('chalk');
 | 
						|
const inquirer = require('inquirer');
 | 
						|
const { kebabCase } = require('lodash');
 | 
						|
const FilesContentSearch = require('../utils/search-files-content');
 | 
						|
const { readAllTranslationFiles, writeAllTranslationFiles } = require('../utils/translation-files');
 | 
						|
const { findDuplicatedTranslations } = require('./find-duplicated-translation');
 | 
						|
 | 
						|
const fcs = new FilesContentSearch(
 | 
						|
  [path.join(__dirname, '../../../')],
 | 
						|
  ['**/*.js'],
 | 
						|
  ['**/node_modules/**', '**/cache/**', '**/build/**']
 | 
						|
);
 | 
						|
 | 
						|
const mapDuplicates = async (duplicatesObject, fn) => {
 | 
						|
  Object.entries(duplicatesObject).forEach(([value, pkgs]) => fn(value, pkgs));
 | 
						|
};
 | 
						|
 | 
						|
const mapDuplicateValues = async (pkgs, fn) => {
 | 
						|
  Object.entries(pkgs).forEach(([packageName, keys]) => {
 | 
						|
    keys.forEach((key) => fn(key, packageName));
 | 
						|
  });
 | 
						|
};
 | 
						|
 | 
						|
const promptShouldMerge = async () => {
 | 
						|
  return (
 | 
						|
    await inquirer.prompt({
 | 
						|
      type: 'confirm',
 | 
						|
      message: 'Should merge?',
 | 
						|
      name: 'shouldMerge',
 | 
						|
      default: false,
 | 
						|
    })
 | 
						|
  ).shouldMerge;
 | 
						|
};
 | 
						|
 | 
						|
const promptTargetKey = async (valueGroup) => {
 | 
						|
  return (
 | 
						|
    await inquirer.prompt({
 | 
						|
      type: 'input',
 | 
						|
      name: 'targetKey',
 | 
						|
      message: 'Target key name:',
 | 
						|
      default: `global.${kebabCase(valueGroup[0].value)}`,
 | 
						|
    })
 | 
						|
  ).targetKey;
 | 
						|
};
 | 
						|
 | 
						|
const printToMerge = (valueGroup) => {
 | 
						|
  console.log(`Value: "${chalk.yellow(valueGroup[0].value)}"`);
 | 
						|
 | 
						|
  console.table(
 | 
						|
    valueGroup.map((keyGroup) => ({
 | 
						|
      key: keyGroup.key,
 | 
						|
      package: keyGroup.packageName,
 | 
						|
      usageCount: keyGroup.resultsCount,
 | 
						|
    }))
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
const applyPackageScope = (packageName, searchResults) => {
 | 
						|
  return searchResults.filter(
 | 
						|
    (result) => packageName === 'core/admin' || result.path.includes(packageName)
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
// Filters out duplicated transtations that are not in use
 | 
						|
const getValuesToMerge = (keyUsage) =>
 | 
						|
  keyUsage
 | 
						|
    .map((value) => value.dups.filter((dup) => dup.resultsCount > 0))
 | 
						|
    .filter((value) => value.length > 1);
 | 
						|
 | 
						|
// Returns an array of duplicated translations that are in use in the codebase
 | 
						|
// (found in at least one .js files)
 | 
						|
const getKeysUsage = (duplicatesObject) => {
 | 
						|
  const keyUsage = [];
 | 
						|
 | 
						|
  mapDuplicates(duplicatesObject, (value, pkgs) => {
 | 
						|
    const dups = [];
 | 
						|
 | 
						|
    mapDuplicateValues(pkgs, (key, packageName) => {
 | 
						|
      const searchResults = applyPackageScope(packageName, [
 | 
						|
        ...fcs.searchString(`id: '${key}'`),
 | 
						|
        ...fcs.searchString(`id: getTrad('${key}')`),
 | 
						|
      ]);
 | 
						|
      const resultsCount = searchResults.reduce((acc, cur) => cur.matches.length + acc, 0);
 | 
						|
 | 
						|
      dups.push({
 | 
						|
        key,
 | 
						|
        value,
 | 
						|
        packageName,
 | 
						|
        resultsCount,
 | 
						|
        replaceAll: (replaceValue) =>
 | 
						|
          searchResults.forEach((result) => result.replaceAll(replaceValue)),
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    keyUsage.push({ value, dups });
 | 
						|
  });
 | 
						|
 | 
						|
  return keyUsage;
 | 
						|
};
 | 
						|
 | 
						|
// Handles the merging in translation files
 | 
						|
// Removes duplicated translations + creates a new shared key in the core/admin en.json file
 | 
						|
const updateTranslationFiles = (keyGroup, targetKey) => {
 | 
						|
  const translationFiles = {};
 | 
						|
  readAllTranslationFiles().forEach((file) => {
 | 
						|
    translationFiles[file.packageName] = file;
 | 
						|
  });
 | 
						|
 | 
						|
  if (translationFiles[keyGroup.packageName].fileContent[keyGroup.key] === keyGroup.value) {
 | 
						|
    delete translationFiles[keyGroup.packageName].fileContent[keyGroup.key];
 | 
						|
  }
 | 
						|
  translationFiles['core/admin'].fileContent[targetKey] = keyGroup.value;
 | 
						|
 | 
						|
  writeAllTranslationFiles(Object.values(translationFiles));
 | 
						|
};
 | 
						|
 | 
						|
// Displays and prompt for every detected duplications
 | 
						|
// Triggers the merge if necessary
 | 
						|
const merge = async (valuesToMerge) => {
 | 
						|
  let current = 1;
 | 
						|
  let mergedCount = 0;
 | 
						|
 | 
						|
  for (const valueGroup of valuesToMerge) {
 | 
						|
    // Display
 | 
						|
    console.clear();
 | 
						|
    console.log(`${current}/${valuesToMerge.length}`);
 | 
						|
    printToMerge(valueGroup);
 | 
						|
 | 
						|
    // Prompt and merge
 | 
						|
    if (await promptShouldMerge()) {
 | 
						|
      const targetKey = await promptTargetKey(valueGroup);
 | 
						|
      valueGroup.forEach((keyGroup) => {
 | 
						|
        updateTranslationFiles(keyGroup, targetKey);
 | 
						|
        keyGroup.replaceAll(`id: '${targetKey}'`);
 | 
						|
        mergedCount += 1;
 | 
						|
      });
 | 
						|
    }
 | 
						|
    current += 1;
 | 
						|
  }
 | 
						|
 | 
						|
  console.log(`Merged ${mergedCount} keys`);
 | 
						|
};
 | 
						|
 | 
						|
(async () => {
 | 
						|
  await fcs.loadFiles();
 | 
						|
 | 
						|
  const duplicates = findDuplicatedTranslations();
 | 
						|
  const keyUsage = getKeysUsage(duplicates);
 | 
						|
  const valuesToMerge = getValuesToMerge(keyUsage);
 | 
						|
 | 
						|
  await merge(valuesToMerge);
 | 
						|
})();
 |