generateI18n.ts 4.63 KB
Newer Older
1
2
#!/usr/bin/env node

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
3
4
5
6
7
8
const fg = require('fast-glob');
const _ = require('lodash');
const fs = require('fs');
const md5 = require('js-md5');
const mkdirp = require('mkdirp');
const rimraf = require('rimraf');
Matija Obreza's avatar
Matija Obreza committed
9
const Path = require('path');
10
const minimist = require('minimist');
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
11

12
13
14
15
16
17
18
19
// console.log('Env', process.env);
// console.log('Args' , process.argv);
// console.log('CWD', process.cwd());
// console.log('env.INIT_CWD', rootDir);

const rootDir = process.cwd();
console.log(`Scanning ${rootDir}`);

20
21
const getPrefix = (path) => {
  console.log(`Converting ${path}`);
22
  return path.substring(path.indexOf('/src/') + '/src/'.length, path.indexOf('/translations.json'));
23
24
};

25
26
27
28
29
30
const args = minimist(process.argv.slice(2));
const moduleName = args.moduleName;
const includedLocales = args.includedLocales;

// console.log(args);

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
31
// TODO fix generated paths
32
fg([`${rootDir}/src/**/translations.json`, `${rootDir}/rc/translations.json`])
33
34
35
36
  .then((entries) => {
    console.log(`Inspecting ${entries}`);
    return entries.filter((e) => ! /\/node_modules\//.test(e));
  })
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
37
38
39
40
41
42
43
44
  .then((entries) => entries.sort((a, b) => getPrefix(a).localeCompare(getPrefix(b))))
  .then((entries) => {
    let result = {};
    entries.forEach((path) => {
      result = { ...result, ...getTranslations(path) };
    });
    return result;
  })
45
  .then((content) => {
46
47
    if (!fs.existsSync(`${rootDir}/locales/en`)) {
      mkdirp.sync(`${rootDir}/locales/en`); // create dir if no exist
48
    }
49
    fs.writeFileSync(`${rootDir}/locales/en/${moduleName || 'translations'}.json`, JSON.stringify(content, null, 2))
50
  })
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
51
  .then(() => {
52
    const content = fs.readFileSync(`${rootDir}/locales/en/${moduleName || 'translations'}.json`);
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
53
54
    JSON.parse(content);
  }).catch((error) => {
55
    console.log(`Error reading resulting locales/en/${moduleName || 'translations'}.json`, error);
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
56
57
58
59
60
    process.exit(-1);
  })
  .then(() => generateHashedLocales());

const generateHashedLocales = () => {
61
62
  const included = includedLocales
    ? includedLocales.replace(/[\[\]]/gi, '').split(',')
63
64
    : [];

65
  rimraf(`${rootDir}/generated/locales`, (err) => { // delete old generated locales
66
    fg([`${rootDir}/locales/**/${moduleName || 'translations'}.json`, ...included]) // scan for all translations files
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
67
68
      .then((entries) => {
        const localeHashMapping = {}; // map commonPath -> pathWithHash
69
        mkdirp(`${rootDir}/generated/locales`, () => {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
70
          entries.forEach((path) => {
Matija Obreza's avatar
Matija Obreza committed
71
            const fullPath = Path.normalize(Path.isAbsolute(path) ? path : Path.join(process.cwd(), path));
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
72
73
            const fileContent = fs.readFileSync(path); // reading content for generating hash
            const contentHash = md5(fileContent);
Matija Obreza's avatar
Matija Obreza committed
74
75
            const mappingPath = fullPath.substring(fullPath.indexOf('/locales'));
            // console.log(`${path} --> ${fullPath} --> ${mappingPath}`);
76
            const newFilePath = path.substring(path.indexOf('/locales')).replace('locales', 'generated/locales').replace('.json', `-${ contentHash }.json`); // adding hash before .json
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
77
            const generatedLocaleDirPath = newFilePath.substring(0, newFilePath.lastIndexOf('/')); // getting all but the filename as folder of locale lang
Matija Obreza's avatar
Matija Obreza committed
78
            console.log(`Mapped ${path} to ${newFilePath}`);
79
80
            mkdirp.sync(`${rootDir}/${generatedLocaleDirPath}`); // create dir if no exist
            fs.writeFileSync(`${rootDir}/${newFilePath}`, fileContent, { flag: 'wx' });
Matija Obreza's avatar
Matija Obreza committed
81
            localeHashMapping[mappingPath] = newFilePath.replace('./generated', ''); // deleting '/generated' from new path for further loading
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
82
            // console.log(`Generated ${ newFilePath } for ${ path }`);
83
            if (mappingPath.endsWith(`/${moduleName}.json`)) {
84
              console.log(`Registering 'translations.json' mapping for ${mappingPath}`);
85
              localeHashMapping[mappingPath.replace(`/${moduleName}.json`, '/translations.json')] = localeHashMapping[mappingPath];
86
            }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
87
          });
Matija Obreza's avatar
Matija Obreza committed
88
          console.log('Locale mappings', localeHashMapping);
89
          fs.writeFileSync(`${rootDir}/generated/locales/localesMapping.json`, JSON.stringify(localeHashMapping), { encoding: 'utf8' }); // after all locales moved creating file with mappings
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
        });
      });
  });
};


const getTranslations = (path) => {
  const prefix = getPrefix(path);
  console.log('Loading translations of module', prefix);
  const fileContent = fs.readFileSync(path, 'utf8');
  try {
    const i18n = JSON.parse(fileContent);

    if (prefix === '/') {
      return i18n;
    } else {
      const moduleI18n = {};
      moduleI18n[prefix] = i18n;
      return moduleI18n;
    }
  } catch (error) {
    console.log(`Invalid JSON in ${path}`, error);
    process.exit(-1);
  }
};