mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-05-31 14:11:58 +05:30
Basic functionality for locale change. Draft implementation of tools for working with i18n
This commit is contained in:
3
scripts/.babelrc
Normal file
3
scripts/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"breakConfig": true
|
||||
}
|
147
scripts/i18n-collect.js
Normal file
147
scripts/i18n-collect.js
Normal file
@@ -0,0 +1,147 @@
|
||||
import fs from 'fs';
|
||||
import {sync as globSync} from 'glob';
|
||||
import {sync as mkdirpSync} from 'mkdirp';
|
||||
import chalk from 'chalk';
|
||||
import prompt from 'prompt';
|
||||
|
||||
const MESSAGES_PATTERN = `../dist/messages/**/*.json`;
|
||||
const LANG_DIR = `../src/i18n`;
|
||||
const DEFAULT_LOCALE = 'en';
|
||||
const SUPPORTED_LANGS = [DEFAULT_LOCALE].concat('ru');
|
||||
|
||||
/**
|
||||
* Aggregates the default messages that were extracted from the app's
|
||||
* React components via the React Intl Babel plugin. An error will be thrown if
|
||||
* there are messages in different components that use the same `id`. The result
|
||||
* is a flat collection of `id: message` pairs for the app's default locale.
|
||||
*/
|
||||
let idToFileMap = {};
|
||||
let duplicateIds = [];
|
||||
let defaultMessages = globSync(MESSAGES_PATTERN)
|
||||
.map((filename) => [filename, JSON.parse(fs.readFileSync(filename, 'utf8'))])
|
||||
.reduce((collection, [file, descriptors]) => {
|
||||
descriptors.forEach(({id, defaultMessage}) => {
|
||||
if (collection.hasOwnProperty(id)) {
|
||||
duplicateIds.push(id);
|
||||
}
|
||||
|
||||
collection[id] = defaultMessage;
|
||||
idToFileMap[id] = (idToFileMap[id] || []).concat(file);
|
||||
});
|
||||
|
||||
return collection;
|
||||
}, {});
|
||||
|
||||
if (duplicateIds.length) {
|
||||
console.log('\nFound duplicated ids:');
|
||||
duplicateIds.forEach((id) => console.log(`${chalk.yellow(id)}:\n - ${idToFileMap[id].join('\n - ')}\n`));
|
||||
console.log(chalk.red('Please correct the errors above to proceed further!'));
|
||||
return;
|
||||
}
|
||||
|
||||
duplicateIds = null;
|
||||
idToFileMap = null;
|
||||
|
||||
/**
|
||||
* Making a diff with the previous DEFAULT_LOCALE version
|
||||
*/
|
||||
const defaultMessagesPath = `${LANG_DIR}/${DEFAULT_LOCALE}.json`;
|
||||
let keysToUpdate = [];
|
||||
let keysToAdd = [];
|
||||
let keysToRemove = [];
|
||||
const isNotMarked = (value) => value.slice(0, 2) !== '--';
|
||||
try {
|
||||
const prevMessages = JSON.parse(fs.readFileSync(defaultMessagesPath, 'utf8'));
|
||||
keysToAdd = Object.keys(defaultMessages).filter((key) => !prevMessages[key]);
|
||||
keysToRemove = Object.keys(prevMessages).filter((key) => !defaultMessages[key]).filter(isNotMarked);
|
||||
keysToUpdate = Object.entries(prevMessages).reduce((acc, [key, message]) =>
|
||||
acc.concat(defaultMessages[key] && defaultMessages[key] !== message ? key : [])
|
||||
, []);
|
||||
} catch(e) {
|
||||
console.log(chalk.yellow(`Can not read ${defaultMessagesPath}. The new file will be created.`), e);
|
||||
}
|
||||
|
||||
if (!keysToAdd.length && !keysToRemove.length && !keysToUpdate.length) {
|
||||
return console.log(chalk.green('Everything is up to date!'));
|
||||
}
|
||||
|
||||
console.log(chalk.magenta(`The diff relative to default locale (${DEFAULT_LOCALE}) is:`));
|
||||
|
||||
if (keysToRemove.length) {
|
||||
console.log('The following keys will be removed:');
|
||||
console.log(chalk.red('\n - ') + keysToRemove.join(chalk.red('\n - ')) + '\n');
|
||||
}
|
||||
|
||||
if (keysToAdd.length) {
|
||||
console.log('The following keys will be added:');
|
||||
console.log(chalk.green('\n + ') + keysToAdd.join(chalk.green('\n + ')) + '\n');
|
||||
}
|
||||
|
||||
if (keysToUpdate.length) {
|
||||
console.log('The following keys will be updated:');
|
||||
console.log(chalk.yellow('\n @ ') + keysToUpdate.join(chalk.yellow('\n @ ')) + '\n');
|
||||
}
|
||||
|
||||
prompt.start();
|
||||
prompt.get({
|
||||
properties: {
|
||||
apply: {
|
||||
description: 'Apply changes? [Y/n]',
|
||||
pattern: /^y|n$/i,
|
||||
message: 'Please enter "y" or "n"',
|
||||
default: 'y',
|
||||
before: (value) => value.toLowerCase() === 'y'
|
||||
}
|
||||
}
|
||||
}, (err, resp) => {
|
||||
console.log('\n');
|
||||
|
||||
if (err || !resp.apply) {
|
||||
return console.log(chalk.red('Aborted'));
|
||||
}
|
||||
|
||||
buildLocales();
|
||||
|
||||
console.log(chalk.green('All locales was successfuly built'));
|
||||
});
|
||||
|
||||
|
||||
function buildLocales() {
|
||||
mkdirpSync(LANG_DIR);
|
||||
|
||||
SUPPORTED_LANGS.map((lang) => {
|
||||
const destPath = `${LANG_DIR}/${lang}.json`;
|
||||
|
||||
let newMessages = {};
|
||||
try {
|
||||
newMessages = JSON.parse(fs.readFileSync(defaultMessagesPath, 'utf8'));
|
||||
} catch (e) {
|
||||
console.log(chalk.yellow(`Can not read ${defaultMessagesPath}. The new file will be created.`), e);
|
||||
}
|
||||
|
||||
keysToRemove.forEach((key) => {
|
||||
delete newMessages[key];
|
||||
});
|
||||
keysToUpdate.forEach((key) => {
|
||||
newMessages[`--${key}`] = newMessages[key];
|
||||
});
|
||||
keysToAdd.concat(keysToUpdate).forEach((key) => {
|
||||
newMessages[key] = defaultMessages[key];
|
||||
});
|
||||
|
||||
const sortedKeys = Object.keys(newMessages).sort((a, b) => {
|
||||
a = a.replace(/^\-+/, '');
|
||||
b = b.replace(/^\-+/, '');
|
||||
|
||||
return a < b || !isNotMarked(a) ? -1 : 1;
|
||||
});
|
||||
|
||||
const sortedNewMessages = sortedKeys.reduce((acc, key) => {
|
||||
acc[key] = newMessages[key];
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
fs.writeFileSync(destPath, JSON.stringify(sortedNewMessages, null, 4) + '\n');
|
||||
});
|
||||
}
|
15
scripts/package.json
Normal file
15
scripts/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "scripts",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "i18n-build.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.3"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user