auto-lang 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/package.json +27 -0
- package/src/index.js +114 -0
- package/src/translations/en.json +1847 -0
- package/src/translations/fr.json +1836 -0
- package/src/translations/tr.json +1836 -0
- package/src/translations/types/index.d.ts +2093 -0
- package/src/utils/Logger.mjs +7 -0
package/README.md
ADDED
package/package.json
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"name": "auto-lang",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "Automatically create language json files for internationalization",
|
5
|
+
"main": "./src/index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"keywords": ["Internationalization", "node", "i18n"],
|
10
|
+
"author": "Lafen Lesley <lesleytech6@gmail.com> (https://github.com/lesleytech/)",
|
11
|
+
"homepage": "https://github.com/lesleytech/auto-lang#readme",
|
12
|
+
"repository": {
|
13
|
+
"type": "git",
|
14
|
+
"url": "https://github.com/lesleytech/auto-lang.git"
|
15
|
+
},
|
16
|
+
"license": "ISC",
|
17
|
+
"bin": "./src/index.js",
|
18
|
+
"type": "module",
|
19
|
+
"dependencies": {
|
20
|
+
"chalk": "^5.0.1",
|
21
|
+
"commander": "^9.4.0",
|
22
|
+
"json-to-ts": "^1.7.0",
|
23
|
+
"nanospinner": "^1.1.0",
|
24
|
+
"prettier": "^2.7.1",
|
25
|
+
"translate": "^1.4.1"
|
26
|
+
}
|
27
|
+
}
|
package/src/index.js
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
import path from 'path';
|
4
|
+
import { promises as fs } from 'fs';
|
5
|
+
import { existsSync } from 'fs';
|
6
|
+
import { Command } from 'commander';
|
7
|
+
import chalk from 'chalk';
|
8
|
+
import { exit } from 'process';
|
9
|
+
import { createSpinner } from 'nanospinner';
|
10
|
+
import translate from 'translate';
|
11
|
+
import { Logger } from './utils/Logger.mjs';
|
12
|
+
import JsonToTS from 'json-to-ts';
|
13
|
+
import prettier from 'prettier';
|
14
|
+
|
15
|
+
const program = new Command();
|
16
|
+
const nodeMajVer = parseInt(process.version.substring(1).split('.')[0]);
|
17
|
+
|
18
|
+
if (nodeMajVer < 14) {
|
19
|
+
Logger.error(`Node version >= 14.x.x is required`);
|
20
|
+
|
21
|
+
exit(1);
|
22
|
+
}
|
23
|
+
|
24
|
+
program
|
25
|
+
.name('auto-lang')
|
26
|
+
.description('Generate translation files for multiple languages')
|
27
|
+
.version('1.0.0')
|
28
|
+
.requiredOption('-f, --from <lang>', 'language to translate from')
|
29
|
+
.requiredOption(
|
30
|
+
'-t, --to <lang...>',
|
31
|
+
'Languages to translate to (Seperated by space)'
|
32
|
+
)
|
33
|
+
.parse();
|
34
|
+
|
35
|
+
const { from, to } = program.opts();
|
36
|
+
|
37
|
+
const inputFile = path.join(process.cwd(), 'translations', `${from}.json`);
|
38
|
+
|
39
|
+
if (!existsSync(inputFile)) {
|
40
|
+
Logger.error(`File 'translations/${from}.json' not found`);
|
41
|
+
exit(1);
|
42
|
+
}
|
43
|
+
|
44
|
+
async function makeTranslatedCopy(obj1, obj2, options) {
|
45
|
+
for (let [key, value] of Object.entries(obj1)) {
|
46
|
+
if (typeof value === 'object') {
|
47
|
+
obj2[key] = {};
|
48
|
+
await makeTranslatedCopy(value, obj2[key], options);
|
49
|
+
} else {
|
50
|
+
obj2[key] = await translate(value, { from, to: options.to });
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
const getTranslation = (inputJson, language) =>
|
56
|
+
new Promise(async (resolve, reject) => {
|
57
|
+
const translatedObj = {};
|
58
|
+
|
59
|
+
await makeTranslatedCopy(inputJson, translatedObj, { to: language });
|
60
|
+
|
61
|
+
resolve(JSON.stringify(translatedObj, null, 4));
|
62
|
+
});
|
63
|
+
|
64
|
+
async function createDeclarationFile(json) {
|
65
|
+
const spinner = createSpinner('Creating typescript declaration file').start();
|
66
|
+
|
67
|
+
const interfaces = JsonToTS(json, { rootName: 'GlobalTranslation' });
|
68
|
+
const typesDir = path.join(process.cwd(), 'translations', 'types');
|
69
|
+
|
70
|
+
if (!existsSync(typesDir)) {
|
71
|
+
fs.mkdir(typesDir);
|
72
|
+
}
|
73
|
+
|
74
|
+
const declarationFile = path.join(typesDir, 'index.d.ts');
|
75
|
+
|
76
|
+
const result = `
|
77
|
+
/* eslint-disable no-var */
|
78
|
+
|
79
|
+
declare global {
|
80
|
+
${interfaces[0]}\n\n
|
81
|
+
}
|
82
|
+
|
83
|
+
${interfaces.slice(1).join('\n\n')}
|
84
|
+
|
85
|
+
export {};
|
86
|
+
`;
|
87
|
+
|
88
|
+
const formattedResult = prettier.format(result, { parser: 'typescript' });
|
89
|
+
|
90
|
+
fs.writeFile(declarationFile, formattedResult);
|
91
|
+
spinner.success({ text: 'TS declaration file created' });
|
92
|
+
}
|
93
|
+
|
94
|
+
async function translateFile(inputFile) {
|
95
|
+
const inputJson = JSON.parse(
|
96
|
+
await fs.readFile(inputFile, { encoding: 'utf-8' })
|
97
|
+
);
|
98
|
+
let spinner, langFile, tranlatedJson;
|
99
|
+
|
100
|
+
return inputJson;
|
101
|
+
for (let lang of to) {
|
102
|
+
langFile = path.join(process.cwd(), 'translations', `${lang}.json`);
|
103
|
+
spinner = createSpinner(`Translating to ${lang}...`).start();
|
104
|
+
|
105
|
+
tranlatedJson = await getTranslation(inputJson, lang);
|
106
|
+
// await sleep(1000);
|
107
|
+
await fs.writeFile(langFile, tranlatedJson);
|
108
|
+
|
109
|
+
spinner.success({ text: `Complete` });
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
const json = await translateFile(inputFile);
|
114
|
+
await createDeclarationFile(json);
|