auto-lang 1.0.2 → 1.0.5
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 +13 -10
- package/package.json +2 -2
- package/src/index.js +52 -38
- package/src/test.ts +3 -0
- package/src/utils/validation.mjs +37 -0
package/README.md
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
# Auto Lang
|
2
2
|
|
3
|
-
Generate translation files for multiple languages
|
3
|
+
Generate translation files for multiple languages.
|
4
|
+
|
5
|
+
Write once for a single language and automatically get translated json files for others.
|
4
6
|
## Installation
|
5
|
-
### npm
|
6
|
-
|
7
|
-
### yarn
|
8
|
-
|
7
|
+
### Using npm
|
8
|
+
$ npm install auto-lang
|
9
|
+
### Using yarn
|
10
|
+
$ yarn add auto-lang
|
9
11
|
|
10
12
|
## Usage
|
11
13
|
Run `auto-lang [options]`
|
12
14
|
|
13
15
|
### Options
|
14
16
|
|
15
|
-
-V, --version
|
16
|
-
-f, --from <lang>
|
17
|
-
-t, --to <lang...>
|
18
|
-
-
|
19
|
-
-
|
17
|
+
-V, --version output the version number
|
18
|
+
-f, --from <lang> language to translate from
|
19
|
+
-t, --to <lang...> languages to translate to (seperated by space)
|
20
|
+
-d, --dir <directory> directory containing the language files (default: "translations")
|
21
|
+
-g, --gen-type <lang> generate types from language file
|
22
|
+
-h, --help display help for command
|
package/package.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "auto-lang",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.5",
|
4
4
|
"description": "Automatically create language json files for internationalization",
|
5
5
|
"main": "./src/index.js",
|
6
6
|
"scripts": {
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
8
8
|
},
|
9
|
-
"keywords": ["Internationalization", "node", "i18n"],
|
9
|
+
"keywords": ["Internationalization", "node", "i18n", "translate"],
|
10
10
|
"author": "Lafen Lesley <lesleytech6@gmail.com> (https://github.com/lesleytech/)",
|
11
11
|
"homepage": "https://github.com/lesleytech/auto-lang#readme",
|
12
12
|
"repository": {
|
package/src/index.js
CHANGED
@@ -11,6 +11,10 @@ import JsonToTS from 'json-to-ts';
|
|
11
11
|
import prettier from 'prettier';
|
12
12
|
|
13
13
|
import { Logger } from './utils/Logger.mjs';
|
14
|
+
import chalk from 'chalk';
|
15
|
+
import { validateOptions } from './utils/validation.mjs';
|
16
|
+
|
17
|
+
const APP_VERSION = '1.0.5';
|
14
18
|
|
15
19
|
const program = new Command();
|
16
20
|
const nodeMajVer = parseInt(process.version.substring(1).split('.')[0]);
|
@@ -23,24 +27,28 @@ if (nodeMajVer < 14) {
|
|
23
27
|
|
24
28
|
program
|
25
29
|
.name('auto-lang')
|
26
|
-
.description('Generate translation files for multiple languages')
|
27
|
-
.version(
|
28
|
-
.
|
29
|
-
.
|
30
|
+
.description('Generate translation files for multiple languages (i18n)')
|
31
|
+
.version(APP_VERSION)
|
32
|
+
.option('-f, --from <lang>', 'language to translate from')
|
33
|
+
.option(
|
30
34
|
'-t, --to <lang...>',
|
31
|
-
'
|
35
|
+
'languages to translate to (seperated by space)'
|
36
|
+
)
|
37
|
+
.option(
|
38
|
+
'-d, --dir <directory>',
|
39
|
+
'directory containing the language files',
|
40
|
+
'translations'
|
32
41
|
)
|
33
|
-
.option('-g, --gen-
|
42
|
+
.option('-g, --gen-type <lang>', 'generate types from language file')
|
34
43
|
.parse();
|
35
44
|
|
36
|
-
const { from, to,
|
37
|
-
|
38
|
-
|
45
|
+
const { from, to, genType, inputFile, genTypeFile, dir } = validateOptions(
|
46
|
+
program.opts()
|
47
|
+
);
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
49
|
+
const inputJson = JSON.parse(
|
50
|
+
await fs.readFile(inputFile, { encoding: 'utf-8' })
|
51
|
+
);
|
44
52
|
|
45
53
|
async function makeTranslatedCopy(obj1, obj2, options) {
|
46
54
|
for (let [key, value] of Object.entries(obj1)) {
|
@@ -48,12 +56,18 @@ async function makeTranslatedCopy(obj1, obj2, options) {
|
|
48
56
|
obj2[key] = {};
|
49
57
|
await makeTranslatedCopy(value, obj2[key], options);
|
50
58
|
} else {
|
51
|
-
|
59
|
+
try {
|
60
|
+
obj2[key] = await translate(value, { from, to: options.to });
|
61
|
+
} catch (err) {
|
62
|
+
console.log('\n');
|
63
|
+
Logger.error(err.message);
|
64
|
+
exit(1);
|
65
|
+
}
|
52
66
|
}
|
53
67
|
}
|
54
68
|
}
|
55
69
|
|
56
|
-
const getTranslation = (
|
70
|
+
const getTranslation = (language) =>
|
57
71
|
new Promise(async (resolve, reject) => {
|
58
72
|
const translatedObj = {};
|
59
73
|
|
@@ -62,58 +76,58 @@ const getTranslation = (inputJson, language) =>
|
|
62
76
|
resolve(JSON.stringify(translatedObj, null, 4));
|
63
77
|
});
|
64
78
|
|
65
|
-
async function createDeclarationFile(
|
66
|
-
const spinner = createSpinner('Creating
|
79
|
+
async function createDeclarationFile() {
|
80
|
+
const spinner = createSpinner('Creating language type file').start();
|
67
81
|
|
68
|
-
const interfaces = JsonToTS(
|
69
|
-
const typesDir = path.join(process.cwd(),
|
82
|
+
const interfaces = JsonToTS(inputJson, { rootName: 'GlobalTranslationType' });
|
83
|
+
const typesDir = path.join(process.cwd(), dir, 'types');
|
70
84
|
|
71
85
|
if (!existsSync(typesDir)) {
|
72
86
|
fs.mkdir(typesDir);
|
73
87
|
}
|
74
88
|
|
75
|
-
const declarationFile = path.join(typesDir, 'index.
|
89
|
+
const declarationFile = path.join(typesDir, 'index.ts');
|
76
90
|
|
77
91
|
const result = `
|
78
92
|
/* eslint-disable no-var */
|
79
93
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
94
|
+
type NestedKeyOf<ObjectType extends object> = {
|
95
|
+
[Key in keyof ObjectType & string]: ObjectType[Key] extends object
|
96
|
+
? // @ts-ignore
|
97
|
+
\`$\{Key}.$\{NestedKeyOf<ObjectType[Key]>}\`
|
98
|
+
: \`$\{Key}\`
|
99
|
+
}[keyof ObjectType & string]
|
85
100
|
|
86
|
-
export
|
101
|
+
export type GlobalTranslation = NestedKeyOf<GlobalTranslationType>;
|
102
|
+
|
103
|
+
${interfaces.join('\n\n')}
|
87
104
|
`;
|
88
105
|
|
89
106
|
const formattedResult = prettier.format(result, { parser: 'typescript' });
|
90
107
|
|
91
108
|
fs.writeFile(declarationFile, formattedResult);
|
92
|
-
spinner.success({ text: '
|
109
|
+
spinner.success({ text: 'Language type file created' });
|
93
110
|
}
|
94
111
|
|
95
|
-
async function translateFile(
|
96
|
-
const inputJson = JSON.parse(
|
97
|
-
await fs.readFile(inputFile, { encoding: 'utf-8' })
|
98
|
-
);
|
112
|
+
async function translateFile() {
|
99
113
|
let spinner, langFile, tranlatedJson;
|
100
114
|
|
101
115
|
for (let lang of to) {
|
102
|
-
langFile = path.join(process.cwd(),
|
116
|
+
langFile = path.join(process.cwd(), dir, `${lang}.json`);
|
103
117
|
spinner = createSpinner(`Translating to ${lang}...`).start();
|
104
118
|
|
105
|
-
tranlatedJson = await getTranslation(
|
119
|
+
tranlatedJson = await getTranslation(lang);
|
106
120
|
// await sleep(1000);
|
107
121
|
await fs.writeFile(langFile, tranlatedJson);
|
108
122
|
|
109
123
|
spinner.success({ text: `Complete` });
|
110
124
|
}
|
111
|
-
|
112
|
-
return inputJson;
|
113
125
|
}
|
114
126
|
|
115
|
-
|
127
|
+
if (from && to) {
|
128
|
+
await translateFile();
|
129
|
+
}
|
116
130
|
|
117
|
-
if (
|
118
|
-
await createDeclarationFile(
|
131
|
+
if (genType) {
|
132
|
+
await createDeclarationFile();
|
119
133
|
}
|
package/src/test.ts
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
import chalk from 'chalk';
|
2
|
+
import { existsSync } from 'fs';
|
3
|
+
import path from 'path';
|
4
|
+
|
5
|
+
import { Logger } from './Logger.mjs';
|
6
|
+
|
7
|
+
export function validateOptions(opts) {
|
8
|
+
if (!Object.keys(opts).length) {
|
9
|
+
Logger.error(`Invalid arguments. Use ${chalk.gray('--help')} for usage`);
|
10
|
+
|
11
|
+
exit(1);
|
12
|
+
}
|
13
|
+
|
14
|
+
const { to, from, dir, genType } = opts;
|
15
|
+
|
16
|
+
if ((from && !to) || (to && !from)) {
|
17
|
+
Logger.error(
|
18
|
+
`${chalk.gray('--from')} and ${chalk.gray('--to')} are dependent options`
|
19
|
+
);
|
20
|
+
exit(1);
|
21
|
+
}
|
22
|
+
|
23
|
+
const inputFile = path.join(process.cwd(), dir, `${from}.json`);
|
24
|
+
const genTypeFile = path.join(process.cwd(), dir, `${genType}.json`);
|
25
|
+
|
26
|
+
if (!existsSync(inputFile) && from) {
|
27
|
+
Logger.error(`File "${inputFile}" not found`);
|
28
|
+
exit(1);
|
29
|
+
}
|
30
|
+
|
31
|
+
if (!existsSync(genTypeFile) && genType) {
|
32
|
+
Logger.error(`File "${genType}" not found`);
|
33
|
+
exit(1);
|
34
|
+
}
|
35
|
+
|
36
|
+
return { ...opts, inputFile, genTypeFile };
|
37
|
+
}
|