mirror of
https://github.com/strapi/strapi.git
synced 2025-06-27 00:41:25 +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);
|
|
})();
|