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 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
- ```npm i auto-lang```
7
- ### yarn
8
- ```yarn install auto-lang```
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 output the version number
16
- -f, --from <lang> language to translate from
17
- -t, --to <lang...> Languages to translate to (Seperated by space)
18
- -g, --gen-types generate typescript declaration file
19
- -h, --help display help for command
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.2",
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('1.0.2')
28
- .requiredOption('-f, --from <lang>', 'language to translate from')
29
- .requiredOption(
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
- 'Languages to translate to (Seperated by space)'
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-types', 'generate typescript declaration file')
42
+ .option('-g, --gen-type <lang>', 'generate types from language file')
34
43
  .parse();
35
44
 
36
- const { from, to, genTypes } = program.opts();
37
-
38
- const inputFile = path.join(process.cwd(), 'translations', `${from}.json`);
45
+ const { from, to, genType, inputFile, genTypeFile, dir } = validateOptions(
46
+ program.opts()
47
+ );
39
48
 
40
- if (!existsSync(inputFile)) {
41
- Logger.error(`File 'translations/${from}.json' not found`);
42
- exit(1);
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
- obj2[key] = await translate(value, { from, to: options.to });
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 = (inputJson, language) =>
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(json) {
66
- const spinner = createSpinner('Creating typescript declaration file').start();
79
+ async function createDeclarationFile() {
80
+ const spinner = createSpinner('Creating language type file').start();
67
81
 
68
- const interfaces = JsonToTS(json, { rootName: 'GlobalTranslation' });
69
- const typesDir = path.join(process.cwd(), 'translations', 'types');
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.d.ts');
89
+ const declarationFile = path.join(typesDir, 'index.ts');
76
90
 
77
91
  const result = `
78
92
  /* eslint-disable no-var */
79
93
 
80
- declare global {
81
- ${interfaces[0]}\n\n
82
- }
83
-
84
- ${interfaces.slice(1).join('\n\n')}
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: 'TS declaration file created' });
109
+ spinner.success({ text: 'Language type file created' });
93
110
  }
94
111
 
95
- async function translateFile(inputFile) {
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(), 'translations', `${lang}.json`);
116
+ langFile = path.join(process.cwd(), dir, `${lang}.json`);
103
117
  spinner = createSpinner(`Translating to ${lang}...`).start();
104
118
 
105
- tranlatedJson = await getTranslation(inputJson, lang);
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
- const json = await translateFile(inputFile);
127
+ if (from && to) {
128
+ await translateFile();
129
+ }
116
130
 
117
- if (genTypes) {
118
- await createDeclarationFile(json);
131
+ if (genType) {
132
+ await createDeclarationFile();
119
133
  }
package/src/test.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { GlobalTranslation } from './translations/types';
2
+
3
+ const t = (key: GlobalTranslation) => {};
@@ -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
+ }