auto-lang 1.0.5 → 1.0.8
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 +157 -3
- package/package.json +1 -1
- package/src/index.js +4 -6
- package/src/utils/validation.mjs +5 -5
- package/src/test.ts +0 -3
package/README.md
CHANGED
@@ -10,13 +10,167 @@ Write once for a single language and automatically get translated json files for
|
|
10
10
|
$ yarn add auto-lang
|
11
11
|
|
12
12
|
## Usage
|
13
|
-
|
13
|
+
You could either install the package and add a script to `package.json` or use the `npx` command directly from the terminal.
|
14
14
|
|
15
|
-
###
|
15
|
+
### 1. Using the `npx` command
|
16
|
+
$ npx auto-lang [options]
|
17
|
+
|
18
|
+
### 2. Using a script in `package.json`
|
19
|
+
```json
|
20
|
+
{
|
21
|
+
"scripts": {
|
22
|
+
"gen-lang": "auto-lang [options]"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
```
|
26
|
+
|
27
|
+
Now, in the terminal run:
|
28
|
+
|
29
|
+
$ npm run gen-lang
|
30
|
+
|
31
|
+
Or, using yarn:
|
32
|
+
|
33
|
+
$ yarn gen-lang
|
34
|
+
|
35
|
+
**Note:** You can give your script any name you wish. Also, replace `[options]` with any of the options below.
|
36
|
+
|
37
|
+
#### Options
|
16
38
|
|
17
39
|
-V, --version output the version number
|
18
40
|
-f, --from <lang> language to translate from
|
19
41
|
-t, --to <lang...> languages to translate to (seperated by space)
|
20
42
|
-d, --dir <directory> directory containing the language files (default: "translations")
|
21
43
|
-g, --gen-type <lang> generate types from language file
|
22
|
-
-h, --help display help for command
|
44
|
+
-h, --help display help for command
|
45
|
+
|
46
|
+
**Note:** `<lang>` must be a valid [ISO 639-1 language code](https://localizely.com/iso-639-1-list/).
|
47
|
+
|
48
|
+
### Examples
|
49
|
+
|
50
|
+
These examples assume there's a folder `translations` in the root directory the command is executed.
|
51
|
+
|
52
|
+
You can also pass `--dir <directory>` to change the folder that contains your language `json` files.
|
53
|
+
|
54
|
+
There is a file `en.json` in the translations folder
|
55
|
+
|
56
|
+
```json
|
57
|
+
{
|
58
|
+
"GENERAL": {
|
59
|
+
"OK": "OK",
|
60
|
+
"CANCEL": "Cancel",
|
61
|
+
"ACCEPT": "Accept",
|
62
|
+
"DECLINE": "Decline"
|
63
|
+
},
|
64
|
+
"GREETINGS": {
|
65
|
+
"HELLO": "Hello",
|
66
|
+
"HI": "Hi",
|
67
|
+
"GOOD_MORNING": "Good morning"
|
68
|
+
}
|
69
|
+
}
|
70
|
+
```
|
71
|
+
Get translation files for French (fr) and Spanish (es).
|
72
|
+
|
73
|
+
$ npx auto-lang --from en --to fr es
|
74
|
+
|
75
|
+
Two files have been created; `fr.json` and `es.json` in the `translations` folder.
|
76
|
+
|
77
|
+
+-- root
|
78
|
+
| +-- translations
|
79
|
+
| | +-- en.json
|
80
|
+
| | +-- fr.json
|
81
|
+
| | +-- es.json
|
82
|
+
|
83
|
+
```json
|
84
|
+
/* fr.json */
|
85
|
+
|
86
|
+
{
|
87
|
+
"GENERAL": {
|
88
|
+
"OK": "D'ACCORD",
|
89
|
+
"CANCEL": "Annuler",
|
90
|
+
"ACCEPT": "Accepter",
|
91
|
+
"DECLINE": "Déclin"
|
92
|
+
},
|
93
|
+
"GREETINGS": {
|
94
|
+
"HELLO": "Bonjour",
|
95
|
+
"HI": "Salut",
|
96
|
+
"GOOD_MORNING": "Bonjour"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
```
|
100
|
+
|
101
|
+
```json
|
102
|
+
/* es.json */
|
103
|
+
|
104
|
+
{
|
105
|
+
"GENERAL": {
|
106
|
+
"OK": "OK",
|
107
|
+
"CANCEL": "Cancelar",
|
108
|
+
"ACCEPT": "Aceptar",
|
109
|
+
"DECLINE": "Rechazar"
|
110
|
+
},
|
111
|
+
"GREETINGS": {
|
112
|
+
"HELLO": "Hola",
|
113
|
+
"HI": "Hola",
|
114
|
+
"GOOD_MORNING": "Buenos dias"
|
115
|
+
}
|
116
|
+
}
|
117
|
+
```
|
118
|
+
|
119
|
+
If you use typescript in your project, you can generate a typescript file to use in your code.
|
120
|
+
|
121
|
+
$ npx auto-lang --gen-type en
|
122
|
+
|
123
|
+
This will generate a `GlobalTranslation` type based on the structure of the `translations/en.json` file.
|
124
|
+
|
125
|
+
+-- root
|
126
|
+
| +-- translations
|
127
|
+
| | +-- types
|
128
|
+
| | | +-- index.ts
|
129
|
+
| | +-- en.json
|
130
|
+
| | +-- fr.json
|
131
|
+
| | +-- es.json
|
132
|
+
|
133
|
+
```ts
|
134
|
+
/* translations/types/index.ts */
|
135
|
+
|
136
|
+
type NestedKeyOf<ObjectType extends object> = {
|
137
|
+
[Key in keyof ObjectType & string]: ObjectType[Key] extends object
|
138
|
+
? // @ts-ignore
|
139
|
+
`${Key}.${NestedKeyOf<ObjectType[Key]>}`
|
140
|
+
: `${Key}`;
|
141
|
+
}[keyof ObjectType & string];
|
142
|
+
|
143
|
+
export type GlobalTranslation = NestedKeyOf<GlobalTranslationType>;
|
144
|
+
|
145
|
+
interface GlobalTranslationType {
|
146
|
+
GENERAL: GENERAL;
|
147
|
+
GREETINGS: GREETINGS;
|
148
|
+
}
|
149
|
+
|
150
|
+
interface GREETINGS {
|
151
|
+
HELLO: string;
|
152
|
+
HI: string;
|
153
|
+
GOOD_MORNING: string;
|
154
|
+
}
|
155
|
+
|
156
|
+
interface GENERAL {
|
157
|
+
OK: string;
|
158
|
+
CANCEL: string;
|
159
|
+
ACCEPT: string;
|
160
|
+
DECLINE: string;
|
161
|
+
}
|
162
|
+
|
163
|
+
```
|
164
|
+
|
165
|
+
Now you should be able to use `GlobalTranslation` in your code.
|
166
|
+
|
167
|
+
```ts
|
168
|
+
import { GlobalTranslation } from './translations/types';
|
169
|
+
|
170
|
+
const translate = (key: GlobalTranslation) => {
|
171
|
+
// your code
|
172
|
+
};
|
173
|
+
|
174
|
+
translate('GENERAL.ACCEPT'); // Intellisense and type check from GlobalTranslation
|
175
|
+
|
176
|
+
```
|
package/package.json
CHANGED
package/src/index.js
CHANGED
@@ -14,7 +14,7 @@ import { Logger } from './utils/Logger.mjs';
|
|
14
14
|
import chalk from 'chalk';
|
15
15
|
import { validateOptions } from './utils/validation.mjs';
|
16
16
|
|
17
|
-
const APP_VERSION = '1.0.
|
17
|
+
const APP_VERSION = '1.0.8';
|
18
18
|
|
19
19
|
const program = new Command();
|
20
20
|
const nodeMajVer = parseInt(process.version.substring(1).split('.')[0]);
|
@@ -22,7 +22,7 @@ const nodeMajVer = parseInt(process.version.substring(1).split('.')[0]);
|
|
22
22
|
if (nodeMajVer < 14) {
|
23
23
|
Logger.error(`Node version >= 14.x.x is required`);
|
24
24
|
|
25
|
-
exit(1);
|
25
|
+
process.exit(1);
|
26
26
|
}
|
27
27
|
|
28
28
|
program
|
@@ -47,7 +47,7 @@ const { from, to, genType, inputFile, genTypeFile, dir } = validateOptions(
|
|
47
47
|
);
|
48
48
|
|
49
49
|
const inputJson = JSON.parse(
|
50
|
-
await fs.readFile(inputFile, { encoding: 'utf-8' })
|
50
|
+
await fs.readFile(from ? inputFile : genTypeFile, { encoding: 'utf-8' })
|
51
51
|
);
|
52
52
|
|
53
53
|
async function makeTranslatedCopy(obj1, obj2, options) {
|
@@ -61,7 +61,7 @@ async function makeTranslatedCopy(obj1, obj2, options) {
|
|
61
61
|
} catch (err) {
|
62
62
|
console.log('\n');
|
63
63
|
Logger.error(err.message);
|
64
|
-
exit(1);
|
64
|
+
process.exit(1);
|
65
65
|
}
|
66
66
|
}
|
67
67
|
}
|
@@ -89,8 +89,6 @@ async function createDeclarationFile() {
|
|
89
89
|
const declarationFile = path.join(typesDir, 'index.ts');
|
90
90
|
|
91
91
|
const result = `
|
92
|
-
/* eslint-disable no-var */
|
93
|
-
|
94
92
|
type NestedKeyOf<ObjectType extends object> = {
|
95
93
|
[Key in keyof ObjectType & string]: ObjectType[Key] extends object
|
96
94
|
? // @ts-ignore
|
package/src/utils/validation.mjs
CHANGED
@@ -8,7 +8,7 @@ export function validateOptions(opts) {
|
|
8
8
|
if (!Object.keys(opts).length) {
|
9
9
|
Logger.error(`Invalid arguments. Use ${chalk.gray('--help')} for usage`);
|
10
10
|
|
11
|
-
exit(1);
|
11
|
+
process.exit(1);
|
12
12
|
}
|
13
13
|
|
14
14
|
const { to, from, dir, genType } = opts;
|
@@ -17,7 +17,7 @@ export function validateOptions(opts) {
|
|
17
17
|
Logger.error(
|
18
18
|
`${chalk.gray('--from')} and ${chalk.gray('--to')} are dependent options`
|
19
19
|
);
|
20
|
-
exit(1);
|
20
|
+
process.exit(1);
|
21
21
|
}
|
22
22
|
|
23
23
|
const inputFile = path.join(process.cwd(), dir, `${from}.json`);
|
@@ -25,12 +25,12 @@ export function validateOptions(opts) {
|
|
25
25
|
|
26
26
|
if (!existsSync(inputFile) && from) {
|
27
27
|
Logger.error(`File "${inputFile}" not found`);
|
28
|
-
exit(1);
|
28
|
+
process.exit(1);
|
29
29
|
}
|
30
30
|
|
31
31
|
if (!existsSync(genTypeFile) && genType) {
|
32
|
-
Logger.error(`File "${
|
33
|
-
exit(1);
|
32
|
+
Logger.error(`File "${genTypeFile}" not found`);
|
33
|
+
process.exit(1);
|
34
34
|
}
|
35
35
|
|
36
36
|
return { ...opts, inputFile, genTypeFile };
|
package/src/test.ts
DELETED