@lingual/i18n-check 0.2.0 → 0.3.1
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 +139 -87
- package/dist/bin/index.js +72 -52
- package/dist/bin/index.test.d.ts +1 -0
- package/dist/bin/index.test.js +266 -0
- package/dist/errorReporters.js +1 -1
- package/dist/index.js +2 -2
- package/dist/types.d.ts +5 -0
- package/dist/utils/findInvalidi18nTranslations.js +0 -3
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
# Lingual i18n-check
|
|
2
2
|
|
|
3
|
-
**i18n-check**
|
|
4
|
-
|
|
5
|
-
It will compare the defined source language with all target translation files and try to find inconsistencies between source and target files.
|
|
3
|
+
**i18n-check** validates your [ICU](https://github.com/unicode-org/icu) and [i18next](https://www.i18next.com/) translation files and checks for missing and broken translations.
|
|
4
|
+
It compares the defined source language with all target translation files and finds inconsistencies between source and target files.
|
|
6
5
|
You can run these checks as a pre-commit hook or on the CI depending on your use-case and setup.
|
|
7
6
|
|
|
8
|
-

|
|
9
8
|
|
|
10
|
-

|
|
11
10
|
|
|
12
|
-
##
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [General Usage](#general-usage)
|
|
15
|
+
- [CLI Options](#options)
|
|
16
|
+
- [Examples](#examples)
|
|
17
|
+
- [Single folder](#single-folder)
|
|
18
|
+
- [Folder per locale](#folder-per-locale)
|
|
19
|
+
- [Folder per locale with multiple files](#folder-per-locale-with-multiple-files)
|
|
20
|
+
- [Github Action](#as-github-action)
|
|
21
|
+
- [API](#api)
|
|
22
|
+
- [Development](#development)
|
|
23
|
+
- [Links](#links)
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
13
26
|
|
|
14
27
|
Using **yarn**:
|
|
15
28
|
|
|
@@ -29,9 +42,9 @@ Using **pnpm**:
|
|
|
29
42
|
pnpm add --save-dev @lingual/i18n-check
|
|
30
43
|
```
|
|
31
44
|
|
|
32
|
-
After the installation,
|
|
45
|
+
After the installation, i18n-check can either be accessed via defining a command in the `package.json` file or directly in the CLI.
|
|
33
46
|
|
|
34
|
-
Update
|
|
47
|
+
Update your `package.json` and add a new command:
|
|
35
48
|
|
|
36
49
|
```bash
|
|
37
50
|
"scripts": {
|
|
@@ -48,172 +61,197 @@ Alternatively you can also access the library directly:
|
|
|
48
61
|
node_modules/.bin/i18n-check
|
|
49
62
|
```
|
|
50
63
|
|
|
64
|
+
## General Usage
|
|
65
|
+
|
|
66
|
+
For i18n-check to work you need to provide it at a minimum the source locale (`--source, -s`) for the primary language and the path to the locale translation files (`--locales, -l`).
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
yarn i18n:check -s en-US --locales translations/
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Instead of a single source file you can also pass a directory:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
yarn i18n:check -s en-US --locales translations/
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
See the [examples](#examples) for more details.
|
|
81
|
+
|
|
51
82
|
## Options
|
|
52
83
|
|
|
53
|
-
### --
|
|
84
|
+
### --locales, -l
|
|
54
85
|
|
|
55
|
-
With the `-
|
|
86
|
+
With the `-l` or `--locales` option you define which folder or multiple folders you want to run the i18n checks against. It is a **required** option. i18n-check will try to find all target locale files and compare these files against the defined source file(s).
|
|
56
87
|
Check the [example](#examples) to see how different locale translation files are organised and how they can be addressed.
|
|
57
88
|
|
|
58
89
|
```bash
|
|
59
|
-
yarn i18n:check
|
|
90
|
+
yarn i18n:check --locales translations/messageExamples -s en-US
|
|
60
91
|
```
|
|
61
92
|
|
|
62
|
-
### --source
|
|
93
|
+
### --source, -s
|
|
63
94
|
|
|
64
|
-
With the `-s` or `--source` option you define
|
|
65
|
-
Check the [
|
|
95
|
+
With the `-s` or `--source` option you define the source locale to compare all target files against. It is a **required** option. i18n-check will try to find all target locale files and compare these files against the applicable source file(s).
|
|
96
|
+
Check the [examples](#examples) to see how different locale translation files are organised and how they can be addressed.
|
|
66
97
|
|
|
67
98
|
```bash
|
|
68
|
-
yarn i18n:check
|
|
99
|
+
yarn i18n:check --locales translations/messageExamples -s en-US
|
|
69
100
|
```
|
|
70
101
|
|
|
71
|
-
### --format
|
|
102
|
+
### --format, -f
|
|
72
103
|
|
|
73
|
-
By default
|
|
104
|
+
By default i18n-check will validate against any [ICU](https://github.com/unicode-org/icu) compliant translations.
|
|
74
105
|
Additionally the `i18next` format is supported and can be set via the `-f` or `--format` option.
|
|
75
106
|
|
|
76
|
-
There are i18n libraries that have their own specific format, which might not be based on
|
|
107
|
+
There are i18n libraries that have their own specific format, which might not be based on ICU and therefore can not be validated against currently. On a side-note: there might be future support for more specific formats.
|
|
77
108
|
|
|
78
|
-
Hint: If you want to use the `--unused` flag, you should provide
|
|
109
|
+
Hint: If you want to use the `--unused` flag, you should provide react-intl as the format. Also see the [`unused` section](#--unused) for more details.
|
|
79
110
|
|
|
80
111
|
```bash
|
|
81
|
-
yarn i18n:check
|
|
112
|
+
yarn i18n:check --locales translations/i18NextMessageExamples -s en-US -f i18next
|
|
82
113
|
```
|
|
83
114
|
|
|
84
|
-
### --check
|
|
115
|
+
### --check, -c
|
|
85
116
|
|
|
86
|
-
By default
|
|
117
|
+
By default i18n-check will perform a validation against any **missing** and/or **invalid** keys. There are situations where only a specific check should run. By using the `-c` or `--check` option you can specify a specific check to run.
|
|
87
118
|
|
|
88
119
|
The available options are `missingKeys`, which will check against any missing keys in the target files and `invalidKeys` will check for invalid keys, where the target translations has a different type then the one defined in the source file.
|
|
89
120
|
|
|
90
121
|
Check for missing keys:
|
|
91
122
|
|
|
92
123
|
```bash
|
|
93
|
-
yarn i18n:check
|
|
124
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -c missingKeys
|
|
94
125
|
```
|
|
95
126
|
|
|
96
127
|
Check for invalid keys:
|
|
97
128
|
|
|
98
129
|
```bash
|
|
99
|
-
yarn i18n:check
|
|
130
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -c invalidKeys
|
|
100
131
|
```
|
|
101
132
|
|
|
102
|
-
Check for missing
|
|
133
|
+
Check for missing and invalid keys (which is the default):
|
|
103
134
|
|
|
104
135
|
```bash
|
|
105
|
-
yarn i18n:check
|
|
136
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -c missingKeys,invalidKeys
|
|
106
137
|
```
|
|
107
138
|
|
|
108
|
-
### --unused
|
|
139
|
+
### --unused, -u
|
|
109
140
|
|
|
110
|
-
This feature is currently only supported for
|
|
141
|
+
This feature is currently only supported for react-intl and is useful if you need to know which keys exist in your translation files but not in your codebase. Via the `-u` or `--unused` option you provide a source path to the code, which will be parsed to find all unused keys in the primary target language.
|
|
111
142
|
|
|
112
143
|
It is important to note that you must also provide the `-f` or `--format` option with `react-intl` as value. See the [`format` section](#--format) for more information.
|
|
113
144
|
|
|
114
145
|
```bash
|
|
115
|
-
yarn i18n:check
|
|
146
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -u client/ -f react-intl
|
|
116
147
|
```
|
|
117
148
|
|
|
118
|
-
### --reporter
|
|
149
|
+
### --reporter, -r
|
|
119
150
|
|
|
120
151
|
The standard reporting prints out all the missing or invalid keys.
|
|
121
152
|
Using the `-r` or `--reporter` option enables to override the standard error reporting. Passing the `summary` option will print a summary of the missing or invalid keys.
|
|
122
153
|
|
|
123
154
|
```bash
|
|
124
|
-
yarn i18n:check
|
|
155
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -r summary
|
|
125
156
|
```
|
|
126
157
|
|
|
127
|
-
### --exclude
|
|
158
|
+
### --exclude, -e
|
|
128
159
|
|
|
129
|
-
There are situations where we want to exclude a single or multiple files or a single folder or a group of folders. A typical scenario would be that some keys are missing in a specific folder, as they are being work in progress for example. To exclude this or these files/folders you can use the `-e` or `--exclude` option. It expects
|
|
160
|
+
There are situations where we want to exclude a single or multiple files or a single folder or a group of folders. A typical scenario would be that some keys are missing in a specific folder, as they are being work in progress for example. To exclude this or these files/folders you can use the `-e` or `--exclude` option. It expects one or more files and/or folders.
|
|
130
161
|
|
|
131
162
|
To exclude a single file:
|
|
132
163
|
|
|
133
164
|
```bash
|
|
134
|
-
yarn i18n:check
|
|
165
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -e translations/messageExamples/fr-fr.json
|
|
135
166
|
```
|
|
136
167
|
|
|
137
|
-
To exclude multiple files
|
|
168
|
+
To exclude multiple files provide all files:
|
|
138
169
|
|
|
139
170
|
```bash
|
|
140
|
-
yarn i18n:check
|
|
171
|
+
yarn i18n:check --locales translations/messageExamples -s en-US -e translations/messageExamples/fr-fr.json translations/messageExamples/de-at.json
|
|
141
172
|
```
|
|
142
173
|
|
|
143
174
|
To exclude a single folder:
|
|
144
175
|
|
|
145
176
|
```bash
|
|
146
|
-
yarn i18n:check
|
|
177
|
+
yarn i18n:check --locales translations/folderExamples -s en-US -e translations/folderExamples/fr/*
|
|
147
178
|
```
|
|
148
179
|
|
|
149
|
-
Alternatively you can exclude multiple folders by providing
|
|
180
|
+
Alternatively you can exclude multiple folders by providing the folders to be excluded:
|
|
150
181
|
|
|
151
182
|
```bash
|
|
152
|
-
yarn i18n:check
|
|
183
|
+
yarn i18n:check --locales translations/folderExamples -s en-US -e translations/folderExamples/fr/* translations/folderExample/it/*
|
|
153
184
|
```
|
|
154
185
|
|
|
155
|
-
The `--exclude` option also accepts a mix of files and folders, which follows the same pattern as above
|
|
156
|
-
`-e translations/folderExamples/fr
|
|
186
|
+
The `--exclude` option also accepts a mix of files and folders, which follows the same pattern as above, i.e.
|
|
187
|
+
`-e translations/folderExamples/fr/* translations/messageExamples/it.json`
|
|
157
188
|
|
|
158
189
|
## Examples
|
|
159
190
|
|
|
160
|
-
|
|
191
|
+
i18n-check is able to load and validate against different locale folder structures. Depending on how the locale files are organized, there are different configuration options.
|
|
161
192
|
|
|
162
|
-
|
|
193
|
+
### Single folder
|
|
163
194
|
|
|
164
195
|
If all the locales are organized in a **single folder**:
|
|
165
196
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
197
|
+
```
|
|
198
|
+
locales/
|
|
199
|
+
en-en.json
|
|
200
|
+
de-de.json
|
|
201
|
+
```
|
|
169
202
|
|
|
170
203
|
Use the `t` or `target` option to define the directory that should be checked for target files. With the `s` or `source` option you can specify the base/reference file to compare the target files against.
|
|
171
204
|
|
|
172
205
|
```bash
|
|
173
|
-
yarn i18n:check
|
|
206
|
+
yarn i18n:check --locales locales -s locales/en-us.json
|
|
174
207
|
```
|
|
175
208
|
|
|
176
|
-
|
|
209
|
+
### Folder per locale
|
|
177
210
|
|
|
178
211
|
If the locales are **organised as folders** containing a single json file:
|
|
179
212
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
213
|
+
```
|
|
214
|
+
locales/
|
|
215
|
+
en-US/
|
|
216
|
+
index.json
|
|
217
|
+
de-DE/
|
|
218
|
+
index.json
|
|
219
|
+
```
|
|
185
220
|
|
|
186
221
|
Define the `locales` folder as the directory to look for target files.
|
|
187
222
|
|
|
188
223
|
```bash
|
|
189
|
-
yarn i18n:check
|
|
224
|
+
yarn i18n:check --locales locales -s en-US
|
|
190
225
|
```
|
|
191
226
|
|
|
192
|
-
|
|
227
|
+
### Folder per locale with multiple files
|
|
193
228
|
|
|
194
229
|
If the locales are **organised as folders** containing multiple json files:
|
|
195
230
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
231
|
+
```
|
|
232
|
+
locales/
|
|
233
|
+
en-US/
|
|
234
|
+
one.json
|
|
235
|
+
two.json
|
|
236
|
+
three.json
|
|
237
|
+
de-DE/
|
|
238
|
+
one.json
|
|
239
|
+
two.json
|
|
240
|
+
three.json
|
|
241
|
+
```
|
|
205
242
|
|
|
206
|
-
Define the `locales` folder as the directory to look for target files and pass `locales/en-US/` as the `source` option.
|
|
243
|
+
Define the `locales` folder as the directory to look for target files and pass `locales/en-US/` as the `source` option. i18n-check will try to collect all the files in the provided source directory and compare each one against the corresponding files in the target locales.
|
|
207
244
|
|
|
208
245
|
```bash
|
|
209
|
-
yarn i18n:check
|
|
246
|
+
yarn i18n:check --locales locales -s en-US
|
|
210
247
|
```
|
|
211
248
|
|
|
212
249
|
#### Multiple folders containing locales
|
|
213
250
|
|
|
214
251
|
If the locales are **organised as folders** containing multiple json files:
|
|
215
252
|
|
|
216
|
-
|
|
253
|
+
```
|
|
254
|
+
- spaceOne
|
|
217
255
|
- locales/
|
|
218
256
|
- en-US/
|
|
219
257
|
- one.json
|
|
@@ -223,28 +261,29 @@ If the locales are **organised as folders** containing multiple json files:
|
|
|
223
261
|
- one.json
|
|
224
262
|
- two.json
|
|
225
263
|
- three.json
|
|
226
|
-
-
|
|
264
|
+
- spaceTwo
|
|
227
265
|
- locales/
|
|
228
|
-
- en/
|
|
266
|
+
- en-US/
|
|
229
267
|
- one.json
|
|
230
268
|
- two.json
|
|
231
269
|
- three.json
|
|
232
|
-
- de/
|
|
270
|
+
- de-DE/
|
|
233
271
|
- one.json
|
|
234
272
|
- two.json
|
|
235
273
|
- three.json
|
|
274
|
+
```
|
|
236
275
|
|
|
237
|
-
Define the `locales` folder as the directory to look for target files and pass `
|
|
276
|
+
Define the `locales` folder as the directory to look for target files and pass `en-US` as the `source` option. i18n-check will try to collect all the files in the provided source directory and compare each one against the corresponding files in the target locales.
|
|
238
277
|
|
|
239
278
|
```bash
|
|
240
|
-
yarn i18n:check -
|
|
279
|
+
yarn i18n:check -l spaceOne spaceTwo -s en-US
|
|
241
280
|
```
|
|
242
281
|
|
|
243
282
|
## As Github Action
|
|
244
283
|
|
|
245
|
-
We currently do not offer an explicit **Github Action** you can use out of the box, but if you have
|
|
284
|
+
We currently do not offer an explicit **Github Action** you can use out of the box, but if you have i18n-check already installed, you can define your own **YAML** file. The following example can be seen as a starting point that you can adapt to your current setup:
|
|
246
285
|
|
|
247
|
-
```
|
|
286
|
+
```yml
|
|
248
287
|
name: i18n Check
|
|
249
288
|
on:
|
|
250
289
|
pull_request:
|
|
@@ -268,13 +307,17 @@ jobs:
|
|
|
268
307
|
|
|
269
308
|
- name: yarn i18n-check
|
|
270
309
|
run: |
|
|
271
|
-
yarn i18n-check
|
|
310
|
+
yarn i18n-check --locales translations/messageExamples --source en-US
|
|
272
311
|
```
|
|
273
312
|
|
|
313
|
+
The above workflow will return any missing or invalid keys and the action would fail if missing/invalid keys are found:
|
|
314
|
+
|
|
315
|
+

|
|
316
|
+
|
|
274
317
|
## API
|
|
275
318
|
|
|
276
|
-
Aside from using the CLI,
|
|
277
|
-
Start by importing
|
|
319
|
+
Aside from using the CLI, i18n-check also exposes a set of check functions that can be accessed programmatically.
|
|
320
|
+
Start by importing i18n-check:
|
|
278
321
|
|
|
279
322
|
```ts
|
|
280
323
|
import * as i18nCheck from "@lingual/i18n-check";
|
|
@@ -381,47 +424,56 @@ Run `yarn build`, `pnpm run build` or `npm run build` and then depending on the
|
|
|
381
424
|
Basic icu translation example:
|
|
382
425
|
|
|
383
426
|
```bash
|
|
384
|
-
node dist/bin/index.js
|
|
427
|
+
node dist/bin/index.js --locales translations/messageExamples -s en-US
|
|
385
428
|
```
|
|
386
429
|
|
|
387
430
|
Flatted translation keys example:
|
|
388
431
|
|
|
389
432
|
```bash
|
|
390
|
-
node dist/bin/index.js
|
|
433
|
+
node dist/bin/index.js --locales translations/flattenExamples -s en-US
|
|
391
434
|
```
|
|
392
435
|
|
|
393
436
|
i18next translation example:
|
|
394
437
|
|
|
395
438
|
```bash
|
|
396
|
-
node dist/bin/index.js
|
|
439
|
+
node dist/bin/index.js --locales translations/i18NextMessageExamples -s en-US -f i18next
|
|
397
440
|
```
|
|
398
441
|
|
|
399
442
|
Single file translation example:
|
|
400
443
|
|
|
401
444
|
```bash
|
|
402
|
-
node dist/bin/index.js
|
|
445
|
+
node dist/bin/index.js --locales translations/folderExample -s en-US
|
|
403
446
|
```
|
|
404
447
|
|
|
405
448
|
Multiple files per folder translation example:
|
|
406
449
|
|
|
407
450
|
```bash
|
|
408
|
-
node dist/bin/index.js
|
|
451
|
+
node dist/bin/index.js --locales translations/multipleFilesFolderExample/ -s en-US
|
|
409
452
|
```
|
|
410
453
|
|
|
411
454
|
Multiple folders containing locales translation example:
|
|
412
455
|
|
|
413
456
|
```bash
|
|
414
|
-
node dist/bin/index.js
|
|
457
|
+
node dist/bin/index.js --locales translations/folderExample,translations/messageExamples -s en-US
|
|
415
458
|
```
|
|
416
459
|
|
|
417
|
-
|
|
460
|
+
### Tests
|
|
461
|
+
|
|
462
|
+
To run the tests use one of the following commands:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
pnpm test
|
|
466
|
+
```
|
|
418
467
|
|
|
419
|
-
|
|
468
|
+
```bash
|
|
469
|
+
yarn test
|
|
470
|
+
```
|
|
420
471
|
|
|
421
472
|
```bash
|
|
422
|
-
|
|
473
|
+
npm test
|
|
423
474
|
```
|
|
424
475
|
|
|
425
476
|
## Links
|
|
426
477
|
|
|
427
|
-
[
|
|
478
|
+
- [Introducing i18n-check](https://lingual.dev/blog/introducing-i18n-check/)
|
|
479
|
+
- [Twitter](https://twitter.com/lingualdev)
|
package/dist/bin/index.js
CHANGED
|
@@ -22,13 +22,13 @@ const __1 = require("..");
|
|
|
22
22
|
const errorReporters_1 = require("../errorReporters");
|
|
23
23
|
const flattenTranslations_1 = require("../utils/flattenTranslations");
|
|
24
24
|
commander_1.program
|
|
25
|
-
.version("0.
|
|
26
|
-
.option("-
|
|
27
|
-
.option("-s, --source [source
|
|
25
|
+
.version("0.3.0")
|
|
26
|
+
.option("-l, --locales <locales...>", "name of the directory containing the locales to validate")
|
|
27
|
+
.option("-s, --source [source locale]", "the source locale to validate against")
|
|
28
28
|
.option("-f, --format [format type]", "define the specific format, i.e. i18next")
|
|
29
29
|
.option("-c, --check [checks]", "define the specific checks you want to run: invalid, missing. By default the check will validate against missing and invalid keys, i.e. --check invalidKeys,missingKeys")
|
|
30
30
|
.option("-r, --reporter [error reporting style]", "define the reporting style: standard or summary")
|
|
31
|
-
.option("-e, --exclude
|
|
31
|
+
.option("-e, --exclude <exclude...>", "define the file(s) and/or folders(s) that should be excluded from the check")
|
|
32
32
|
.option("-u, --unused [folder]", "define the source path to find all unused keys")
|
|
33
33
|
.parse();
|
|
34
34
|
const getCheckOptions = () => {
|
|
@@ -41,55 +41,37 @@ const getCheckOptions = () => {
|
|
|
41
41
|
.filter((check) => ["invalidKeys", "missingKeys"].includes(check.trim()));
|
|
42
42
|
return checks.length > 0 ? checks : ["invalidKeys", "missingKeys"];
|
|
43
43
|
};
|
|
44
|
-
const
|
|
45
|
-
return
|
|
46
|
-
return fileName.includes(basePathName);
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
const getTargetPath = (paths, sourcePaths, fileName) => {
|
|
50
|
-
const basePath = paths.find((path) => {
|
|
51
|
-
return fileName.includes(path);
|
|
52
|
-
});
|
|
53
|
-
if (!basePath) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
return sourcePaths.find((path) => path.includes(basePath));
|
|
57
|
-
};
|
|
58
|
-
const toArray = (input) => {
|
|
59
|
-
return input
|
|
60
|
-
.trim()
|
|
61
|
-
.split(",")
|
|
62
|
-
.filter((a) => a);
|
|
44
|
+
const isSource = (fileInfo, srcPath) => {
|
|
45
|
+
return (fileInfo.path.some((path) => path.toLowerCase() === srcPath.toLowerCase()) || fileInfo.name.toLowerCase().slice(0, -5) === srcPath.toLowerCase());
|
|
63
46
|
};
|
|
64
47
|
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
48
|
const start = performance.now();
|
|
66
49
|
const srcPath = commander_1.program.getOptionValue("source");
|
|
67
|
-
const
|
|
50
|
+
const localePath = commander_1.program.getOptionValue("locales");
|
|
68
51
|
const format = commander_1.program.getOptionValue("format");
|
|
69
52
|
const exclude = commander_1.program.getOptionValue("exclude");
|
|
70
53
|
const unusedSrcPath = commander_1.program.getOptionValue("unused");
|
|
71
54
|
if (!srcPath) {
|
|
72
|
-
console.log(chalk_1.default.red("Source
|
|
55
|
+
console.log(chalk_1.default.red("Source not found. Please provide a valid source locale, i.e. -s en-US"));
|
|
73
56
|
(0, process_1.exit)(1);
|
|
74
57
|
}
|
|
75
|
-
if (!
|
|
76
|
-
console.log(chalk_1.default.red("
|
|
58
|
+
if (!localePath || localePath.length === 0) {
|
|
59
|
+
console.log(chalk_1.default.red("Locale file(s) not found. Please provide valid locale file(s), i.e. -locales translations/"));
|
|
77
60
|
(0, process_1.exit)(1);
|
|
78
61
|
}
|
|
79
|
-
const excludedPaths = exclude ?
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
const isMultiFolders = targetPathFolders.length > 1;
|
|
62
|
+
const excludedPaths = exclude !== null && exclude !== void 0 ? exclude : [];
|
|
63
|
+
const localePathFolders = localePath;
|
|
64
|
+
const isMultiFolders = localePathFolders.length > 1;
|
|
83
65
|
let srcFiles = [];
|
|
84
|
-
let
|
|
66
|
+
let localeFiles = [];
|
|
85
67
|
const pattern = isMultiFolders
|
|
86
|
-
? `{${
|
|
87
|
-
: `${
|
|
68
|
+
? `{${localePath.join(",").trim()}}/**/*.json`
|
|
69
|
+
: `${localePath.join(",").trim()}/**/*.json`;
|
|
88
70
|
const files = yield (0, glob_1.glob)(pattern, {
|
|
89
71
|
ignore: ["node_modules/**"].concat(excludedPaths),
|
|
90
72
|
});
|
|
91
73
|
console.log("i18n translations checker");
|
|
92
|
-
console.log(chalk_1.default.gray(`Source
|
|
74
|
+
console.log(chalk_1.default.gray(`Source: ${srcPath}`));
|
|
93
75
|
if (format) {
|
|
94
76
|
console.log(chalk_1.default.blackBright(`Selected format is: ${format}`));
|
|
95
77
|
}
|
|
@@ -97,38 +79,76 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
97
79
|
checks: getCheckOptions(),
|
|
98
80
|
format: format !== null && format !== void 0 ? format : undefined,
|
|
99
81
|
};
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
82
|
+
const fileInfos = [];
|
|
83
|
+
files.sort().forEach((file) => {
|
|
84
|
+
var _a;
|
|
85
|
+
const path = file.split("/");
|
|
86
|
+
const name = (_a = path.pop()) !== null && _a !== void 0 ? _a : "";
|
|
87
|
+
fileInfos.push({
|
|
88
|
+
file,
|
|
89
|
+
path,
|
|
90
|
+
name,
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
fileInfos.forEach(({ file, name, path }) => {
|
|
94
|
+
const rawContent = JSON.parse(fs_1.default.readFileSync(file, "utf-8"));
|
|
95
|
+
const content = (0, flattenTranslations_1.flattenTranslations)(rawContent);
|
|
96
|
+
if (isSource({ file, name, path }, srcPath)) {
|
|
104
97
|
srcFiles.push({
|
|
105
98
|
reference: null,
|
|
106
99
|
name: file,
|
|
107
|
-
content
|
|
100
|
+
content,
|
|
108
101
|
});
|
|
109
102
|
}
|
|
110
103
|
else {
|
|
111
|
-
const
|
|
112
|
-
const reference = (
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
104
|
+
const fullPath = path.join("-");
|
|
105
|
+
const reference = fileInfos.find((fileInfo) => {
|
|
106
|
+
if (!isSource(fileInfo, srcPath)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (fileInfo.path.join("-") === fullPath) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// Check if the folder path matches - ignoring the last folder
|
|
113
|
+
// Then check if the file names are the same
|
|
114
|
+
// Example folder structure:
|
|
115
|
+
// path/to/locales/
|
|
116
|
+
// en-US/
|
|
117
|
+
// one.json
|
|
118
|
+
// two.json
|
|
119
|
+
// three.json
|
|
120
|
+
// de-DE/
|
|
121
|
+
// one.json
|
|
122
|
+
// two.json
|
|
123
|
+
// three.json
|
|
124
|
+
//
|
|
125
|
+
// Referencing: `path/to/locales/en-US/one.json`, `path/to/locales/de-DE/one.json`
|
|
126
|
+
// Non Referencing: `path/to/locales/en-US/one.json`, `path/to/other/locales/de-DE/one.json`
|
|
127
|
+
if (fileInfo.path.slice(0, fileInfo.path.length - 1).join("-") ===
|
|
128
|
+
path.slice(0, path.length - 1).join("-")) {
|
|
129
|
+
return fileInfo.name === name;
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
119
132
|
});
|
|
133
|
+
if (reference) {
|
|
134
|
+
localeFiles.push({
|
|
135
|
+
reference: reference.file,
|
|
136
|
+
name: file,
|
|
137
|
+
content,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
120
140
|
}
|
|
121
141
|
});
|
|
122
142
|
if (srcFiles.length === 0) {
|
|
123
|
-
console.log(chalk_1.default.red("Source
|
|
143
|
+
console.log(chalk_1.default.red("Source not found. Please provide a valid source locale, i.e. -s en-US"));
|
|
124
144
|
(0, process_1.exit)(1);
|
|
125
145
|
}
|
|
126
|
-
if (
|
|
127
|
-
console.log(chalk_1.default.red("
|
|
146
|
+
if (localeFiles.length === 0) {
|
|
147
|
+
console.log(chalk_1.default.red("Locale file(s) not found. Please provide valid locale file(s), i.e. --locales translations/"));
|
|
128
148
|
(0, process_1.exit)(1);
|
|
129
149
|
}
|
|
130
150
|
try {
|
|
131
|
-
const result = (0, __1.checkTranslations)(srcFiles,
|
|
151
|
+
const result = (0, __1.checkTranslations)(srcFiles, localeFiles, options);
|
|
132
152
|
printTranslationResult(result);
|
|
133
153
|
if (unusedSrcPath) {
|
|
134
154
|
const unusedKeys = yield (0, __1.checkUnusedKeys)(srcFiles, unusedSrcPath, options);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const child_process_1 = require("child_process");
|
|
4
|
+
describe("CLI", () => {
|
|
5
|
+
it("should return the missing keys for single folder translations", (done) => {
|
|
6
|
+
(0, child_process_1.exec)("node dist/bin/index.js -s en-US -l translations/flattenExamples", (_error, stdout, _stderr) => {
|
|
7
|
+
const result = stdout.split("Done")[0];
|
|
8
|
+
expect(result).toEqual(`i18n translations checker
|
|
9
|
+
Source: en-US
|
|
10
|
+
|
|
11
|
+
Found missing keys!
|
|
12
|
+
┌───────────────────────────────────────────┬────────────────────────────────┐
|
|
13
|
+
│ file │ key │
|
|
14
|
+
├───────────────────────────────────────────┼────────────────────────────────┤
|
|
15
|
+
│ translations/flattenExamples/de-de.json │ other.nested.three │
|
|
16
|
+
│ translations/flattenExamples/de-de.json │ other.nested.deep.more.final │
|
|
17
|
+
└───────────────────────────────────────────┴────────────────────────────────┘
|
|
18
|
+
|
|
19
|
+
No invalid translations found!
|
|
20
|
+
|
|
21
|
+
`);
|
|
22
|
+
done();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
it("should return the missing/invalid keys for folder per locale with single file", (done) => {
|
|
26
|
+
(0, child_process_1.exec)("node dist/bin/index.js -l translations/folderExample/ -s en-US", (_error, stdout, _stderr) => {
|
|
27
|
+
const result = stdout.split("Done")[0];
|
|
28
|
+
expect(result).toEqual(`i18n translations checker
|
|
29
|
+
Source: en-US
|
|
30
|
+
|
|
31
|
+
Found missing keys!
|
|
32
|
+
┌───────────────────────────────────────────────┬───────────────────────┐
|
|
33
|
+
│ file │ key │
|
|
34
|
+
├───────────────────────────────────────────────┼───────────────────────┤
|
|
35
|
+
│ translations/folderExample/de-DE/index.json │ message.text-format │
|
|
36
|
+
└───────────────────────────────────────────────┴───────────────────────┘
|
|
37
|
+
|
|
38
|
+
Found invalid keys!
|
|
39
|
+
┌───────────────────────────────────────────────┬──────────────────┐
|
|
40
|
+
│ file │ key │
|
|
41
|
+
├───────────────────────────────────────────────┼──────────────────┤
|
|
42
|
+
│ translations/folderExample/de-DE/index.json │ message.select │
|
|
43
|
+
└───────────────────────────────────────────────┴──────────────────┘
|
|
44
|
+
|
|
45
|
+
`);
|
|
46
|
+
done();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it("should return the missing/invalid keys for folder per locale with multiple files", (done) => {
|
|
50
|
+
(0, child_process_1.exec)("node dist/bin/index.js -l translations/multipleFilesFolderExample/ -s en-US", (_error, stdout, _stderr) => {
|
|
51
|
+
const result = stdout.split("Done")[0];
|
|
52
|
+
expect(result).toEqual(`i18n translations checker
|
|
53
|
+
Source: en-US
|
|
54
|
+
|
|
55
|
+
Found missing keys!
|
|
56
|
+
┌──────────────────────────────────────────────────────────┬───────────────────────┐
|
|
57
|
+
│ file │ key │
|
|
58
|
+
├──────────────────────────────────────────────────────────┼───────────────────────┤
|
|
59
|
+
│ translations/multipleFilesFolderExample/de-DE/one.json │ message.text-format │
|
|
60
|
+
│ translations/multipleFilesFolderExample/de-DE/two.json │ test.drive.four │
|
|
61
|
+
└──────────────────────────────────────────────────────────┴───────────────────────┘
|
|
62
|
+
|
|
63
|
+
Found invalid keys!
|
|
64
|
+
┌────────────────────────────────────────────────────────────┬─────────────────────┐
|
|
65
|
+
│ file │ key │
|
|
66
|
+
├────────────────────────────────────────────────────────────┼─────────────────────┤
|
|
67
|
+
│ translations/multipleFilesFolderExample/de-DE/one.json │ message.select │
|
|
68
|
+
│ translations/multipleFilesFolderExample/de-DE/three.json │ multipleVariables │
|
|
69
|
+
└────────────────────────────────────────────────────────────┴─────────────────────┘
|
|
70
|
+
|
|
71
|
+
`);
|
|
72
|
+
done();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
it("should return the missing/invalid keys for folder containing multiple locale folders", (done) => {
|
|
76
|
+
(0, child_process_1.exec)("node dist/bin/index.js -l translations/multipleFoldersExample -s en-US", (_error, stdout, _stderr) => {
|
|
77
|
+
const result = stdout.split("Done")[0];
|
|
78
|
+
expect(result).toEqual(`i18n translations checker
|
|
79
|
+
Source: en-US
|
|
80
|
+
|
|
81
|
+
Found missing keys!
|
|
82
|
+
┌───────────────────────────────────────────────────────────────────────┬───────────────────────┐
|
|
83
|
+
│ file │ key │
|
|
84
|
+
├───────────────────────────────────────────────────────────────────────┼───────────────────────┤
|
|
85
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/one.json │ message.text-format │
|
|
86
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/two.json │ test.drive.four │
|
|
87
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/one.json │ message.plural │
|
|
88
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/two.json │ test.drive.two │
|
|
89
|
+
└───────────────────────────────────────────────────────────────────────┴───────────────────────┘
|
|
90
|
+
|
|
91
|
+
Found invalid keys!
|
|
92
|
+
┌─────────────────────────────────────────────────────────────────────────┬───────────────────────┐
|
|
93
|
+
│ file │ key │
|
|
94
|
+
├─────────────────────────────────────────────────────────────────────────┼───────────────────────┤
|
|
95
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/one.json │ message.select │
|
|
96
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/three.json │ multipleVariables │
|
|
97
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/one.json │ message.text-format │
|
|
98
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/three.json │ numberFormat │
|
|
99
|
+
└─────────────────────────────────────────────────────────────────────────┴───────────────────────┘
|
|
100
|
+
|
|
101
|
+
`);
|
|
102
|
+
done();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
it("should return the missing/invalid keys for multiple locale folders", (done) => {
|
|
106
|
+
(0, child_process_1.exec)("node dist/bin/index.js -l translations/multipleFoldersExample/spaceOne translations/multipleFoldersExample/spaceTwo -s en-US", (_error, stdout, _stderr) => {
|
|
107
|
+
const result = stdout.split("Done")[0];
|
|
108
|
+
expect(result).toEqual(`i18n translations checker
|
|
109
|
+
Source: en-US
|
|
110
|
+
|
|
111
|
+
Found missing keys!
|
|
112
|
+
┌───────────────────────────────────────────────────────────────────────┬───────────────────────┐
|
|
113
|
+
│ file │ key │
|
|
114
|
+
├───────────────────────────────────────────────────────────────────────┼───────────────────────┤
|
|
115
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/one.json │ message.text-format │
|
|
116
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/two.json │ test.drive.four │
|
|
117
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/one.json │ message.plural │
|
|
118
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/two.json │ test.drive.two │
|
|
119
|
+
└───────────────────────────────────────────────────────────────────────┴───────────────────────┘
|
|
120
|
+
|
|
121
|
+
Found invalid keys!
|
|
122
|
+
┌─────────────────────────────────────────────────────────────────────────┬───────────────────────┐
|
|
123
|
+
│ file │ key │
|
|
124
|
+
├─────────────────────────────────────────────────────────────────────────┼───────────────────────┤
|
|
125
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/one.json │ message.select │
|
|
126
|
+
│ translations/multipleFoldersExample/spaceOne/locales/de-DE/three.json │ multipleVariables │
|
|
127
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/one.json │ message.text-format │
|
|
128
|
+
│ translations/multipleFoldersExample/spaceTwo/locales/de-DE/three.json │ numberFormat │
|
|
129
|
+
└─────────────────────────────────────────────────────────────────────────┴───────────────────────┘
|
|
130
|
+
|
|
131
|
+
`);
|
|
132
|
+
done();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
it("should return the missing/invalid keys for all files in the provided locale folders", (done) => {
|
|
136
|
+
(0, child_process_1.exec)("node dist/bin/index.js --source en-US --locales translations/flattenExamples translations/messageExamples", (_error, stdout, _stderr) => {
|
|
137
|
+
const result = stdout.split("Done")[0];
|
|
138
|
+
expect(result).toEqual(`i18n translations checker
|
|
139
|
+
Source: en-US
|
|
140
|
+
|
|
141
|
+
Found missing keys!
|
|
142
|
+
┌───────────────────────────────────────────┬────────────────────────────────┐
|
|
143
|
+
│ file │ key │
|
|
144
|
+
├───────────────────────────────────────────┼────────────────────────────────┤
|
|
145
|
+
│ translations/flattenExamples/de-de.json │ other.nested.three │
|
|
146
|
+
│ translations/flattenExamples/de-de.json │ other.nested.deep.more.final │
|
|
147
|
+
│ translations/messageExamples/de-de.json │ richText │
|
|
148
|
+
│ translations/messageExamples/de-de.json │ yo │
|
|
149
|
+
│ translations/messageExamples/de-de.json │ nesting1 │
|
|
150
|
+
│ translations/messageExamples/de-de.json │ nesting2 │
|
|
151
|
+
│ translations/messageExamples/de-de.json │ nesting3 │
|
|
152
|
+
│ translations/messageExamples/de-de.json │ key1 │
|
|
153
|
+
└───────────────────────────────────────────┴────────────────────────────────┘
|
|
154
|
+
|
|
155
|
+
Found invalid keys!
|
|
156
|
+
┌───────────────────────────────────────────┬─────────────────────┐
|
|
157
|
+
│ file │ key │
|
|
158
|
+
├───────────────────────────────────────────┼─────────────────────┤
|
|
159
|
+
│ translations/messageExamples/de-de.json │ multipleVariables │
|
|
160
|
+
└───────────────────────────────────────────┴─────────────────────┘
|
|
161
|
+
|
|
162
|
+
`);
|
|
163
|
+
done();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
it("should return the missing/invalid keys for all files with source matching folder and source matching file", (done) => {
|
|
167
|
+
(0, child_process_1.exec)("node dist/bin/index.js -l translations/multipleFilesFolderExample translations/flattenExamples -s en-US", (_error, stdout, _stderr) => {
|
|
168
|
+
const result = stdout.split("Done")[0];
|
|
169
|
+
expect(result).toEqual(`i18n translations checker
|
|
170
|
+
Source: en-US
|
|
171
|
+
|
|
172
|
+
Found missing keys!
|
|
173
|
+
┌──────────────────────────────────────────────────────────┬────────────────────────────────┐
|
|
174
|
+
│ file │ key │
|
|
175
|
+
├──────────────────────────────────────────────────────────┼────────────────────────────────┤
|
|
176
|
+
│ translations/flattenExamples/de-de.json │ other.nested.three │
|
|
177
|
+
│ translations/flattenExamples/de-de.json │ other.nested.deep.more.final │
|
|
178
|
+
│ translations/multipleFilesFolderExample/de-DE/one.json │ message.text-format │
|
|
179
|
+
│ translations/multipleFilesFolderExample/de-DE/two.json │ test.drive.four │
|
|
180
|
+
└──────────────────────────────────────────────────────────┴────────────────────────────────┘
|
|
181
|
+
|
|
182
|
+
Found invalid keys!
|
|
183
|
+
┌────────────────────────────────────────────────────────────┬─────────────────────┐
|
|
184
|
+
│ file │ key │
|
|
185
|
+
├────────────────────────────────────────────────────────────┼─────────────────────┤
|
|
186
|
+
│ translations/multipleFilesFolderExample/de-DE/one.json │ message.select │
|
|
187
|
+
│ translations/multipleFilesFolderExample/de-DE/three.json │ multipleVariables │
|
|
188
|
+
└────────────────────────────────────────────────────────────┴─────────────────────┘
|
|
189
|
+
|
|
190
|
+
`);
|
|
191
|
+
done();
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
it("should ignore the excluded file", (done) => {
|
|
195
|
+
(0, child_process_1.exec)("node dist/bin/index.js --source en-US --locales translations/flattenExamples translations/messageExamples --exclude translations/flattenExamples/de-de.json", (_error, stdout, _stderr) => {
|
|
196
|
+
const result = stdout.split("Done")[0];
|
|
197
|
+
expect(result).toEqual(`i18n translations checker
|
|
198
|
+
Source: en-US
|
|
199
|
+
|
|
200
|
+
Found missing keys!
|
|
201
|
+
┌───────────────────────────────────────────┬────────────┐
|
|
202
|
+
│ file │ key │
|
|
203
|
+
├───────────────────────────────────────────┼────────────┤
|
|
204
|
+
│ translations/messageExamples/de-de.json │ richText │
|
|
205
|
+
│ translations/messageExamples/de-de.json │ yo │
|
|
206
|
+
│ translations/messageExamples/de-de.json │ nesting1 │
|
|
207
|
+
│ translations/messageExamples/de-de.json │ nesting2 │
|
|
208
|
+
│ translations/messageExamples/de-de.json │ nesting3 │
|
|
209
|
+
│ translations/messageExamples/de-de.json │ key1 │
|
|
210
|
+
└───────────────────────────────────────────┴────────────┘
|
|
211
|
+
|
|
212
|
+
Found invalid keys!
|
|
213
|
+
┌───────────────────────────────────────────┬─────────────────────┐
|
|
214
|
+
│ file │ key │
|
|
215
|
+
├───────────────────────────────────────────┼─────────────────────┤
|
|
216
|
+
│ translations/messageExamples/de-de.json │ multipleVariables │
|
|
217
|
+
└───────────────────────────────────────────┴─────────────────────┘
|
|
218
|
+
|
|
219
|
+
`);
|
|
220
|
+
done();
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
it("should ignore the excluded folder", (done) => {
|
|
224
|
+
(0, child_process_1.exec)("node dist/bin/index.js --source en-US --locales translations/flattenExamples translations/messageExamples --exclude translations/flattenExamples/*", (_error, stdout, _stderr) => {
|
|
225
|
+
const result = stdout.split("Done")[0];
|
|
226
|
+
expect(result).toEqual(`i18n translations checker
|
|
227
|
+
Source: en-US
|
|
228
|
+
|
|
229
|
+
Found missing keys!
|
|
230
|
+
┌───────────────────────────────────────────┬────────────┐
|
|
231
|
+
│ file │ key │
|
|
232
|
+
├───────────────────────────────────────────┼────────────┤
|
|
233
|
+
│ translations/messageExamples/de-de.json │ richText │
|
|
234
|
+
│ translations/messageExamples/de-de.json │ yo │
|
|
235
|
+
│ translations/messageExamples/de-de.json │ nesting1 │
|
|
236
|
+
│ translations/messageExamples/de-de.json │ nesting2 │
|
|
237
|
+
│ translations/messageExamples/de-de.json │ nesting3 │
|
|
238
|
+
│ translations/messageExamples/de-de.json │ key1 │
|
|
239
|
+
└───────────────────────────────────────────┴────────────┘
|
|
240
|
+
|
|
241
|
+
Found invalid keys!
|
|
242
|
+
┌───────────────────────────────────────────┬─────────────────────┐
|
|
243
|
+
│ file │ key │
|
|
244
|
+
├───────────────────────────────────────────┼─────────────────────┤
|
|
245
|
+
│ translations/messageExamples/de-de.json │ multipleVariables │
|
|
246
|
+
└───────────────────────────────────────────┴─────────────────────┘
|
|
247
|
+
|
|
248
|
+
`);
|
|
249
|
+
done();
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
it("should ignore the excluded multiple files", (done) => {
|
|
253
|
+
(0, child_process_1.exec)("node dist/bin/index.js --source en-US --locales translations/flattenExamples translations/messageExamples --exclude translations/flattenExamples/de-de.json translations/messageExamples/de-de.json", (_error, stdout, _stderr) => {
|
|
254
|
+
const result = stdout.split("Done")[0];
|
|
255
|
+
expect(result).toEqual(`i18n translations checker
|
|
256
|
+
Source: en-US
|
|
257
|
+
|
|
258
|
+
No missing keys found!
|
|
259
|
+
|
|
260
|
+
No invalid translations found!
|
|
261
|
+
|
|
262
|
+
`);
|
|
263
|
+
done();
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
package/dist/errorReporters.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -50,9 +50,9 @@ const checkTranslations = (source, targets, options = { format: "icu", checks: [
|
|
|
50
50
|
};
|
|
51
51
|
};
|
|
52
52
|
exports.checkTranslations = checkTranslations;
|
|
53
|
-
const checkUnusedKeys = (source, codebaseSrc, options = {
|
|
53
|
+
const checkUnusedKeys = (source_1, codebaseSrc_1, ...args_1) => __awaiter(void 0, [source_1, codebaseSrc_1, ...args_1], void 0, function* (source, codebaseSrc, options = {
|
|
54
54
|
format: "react-intl",
|
|
55
|
-
})
|
|
55
|
+
}) {
|
|
56
56
|
if (!options.format || !["react-intl", "i18next"].includes(options.format)) {
|
|
57
57
|
return undefined;
|
|
58
58
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -65,9 +65,6 @@ const hasDiff = (a, b) => {
|
|
|
65
65
|
if (formatElementA.type !== formatElementB.type) {
|
|
66
66
|
return true;
|
|
67
67
|
}
|
|
68
|
-
if (formatElementA.type === "text" && formatElementB.type === "text") {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
68
|
if (formatElementA.type === "tag" && formatElementB.type === "tag") {
|
|
72
69
|
return (formatElementA.raw !== formatElementB.raw ||
|
|
73
70
|
formatElementA.voidElement !== formatElementB.voidElement);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingual/i18n-check",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "i18n translation messages check",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,25 +11,26 @@
|
|
|
11
11
|
"types": "dist/index.d.ts",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc",
|
|
14
|
-
"test": "jest"
|
|
14
|
+
"test": "jest src/ --testPathIgnorePatterns src/bin/*",
|
|
15
|
+
"test:cli": "tsc && jest src/bin/index.test.ts"
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"dist/"
|
|
18
19
|
],
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"@formatjs/cli-lib": "^6.4.2",
|
|
21
|
-
"@formatjs/icu-messageformat-parser": "^2.7.
|
|
22
|
+
"@formatjs/icu-messageformat-parser": "^2.7.8",
|
|
22
23
|
"chalk": "^4.1.2",
|
|
23
|
-
"commander": "^
|
|
24
|
-
"glob": "^
|
|
25
|
-
"typescript": "^5.
|
|
24
|
+
"commander": "^12.1.0",
|
|
25
|
+
"glob": "^11.0.0",
|
|
26
|
+
"typescript": "^5.6.2"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@types/jest": "^29.5.
|
|
29
|
-
"@types/node": "^
|
|
30
|
-
"braces": "
|
|
29
|
+
"@types/jest": "^29.5.13",
|
|
30
|
+
"@types/node": "^22.5.5",
|
|
31
|
+
"braces": "^3.0.3",
|
|
31
32
|
"jest": "^29.7.0",
|
|
32
|
-
"ts-jest": "^29.
|
|
33
|
+
"ts-jest": "^29.2.5"
|
|
33
34
|
},
|
|
34
35
|
"repository": {
|
|
35
36
|
"type": "git",
|