@lingual/i18n-check 0.8.2 → 0.8.3

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
@@ -371,7 +371,7 @@ Aside from using the CLI, i18n-check also exposes a set of check functions that
371
371
  Start by importing i18n-check:
372
372
 
373
373
  ```ts
374
- import * as i18nCheck from "@lingual/i18n-check";
374
+ import * as i18nCheck from '@lingual/i18n-check';
375
375
  ```
376
376
 
377
377
  ### `i18nCheck.checkTranslations(source, targets [, options])`
@@ -379,10 +379,10 @@ import * as i18nCheck from "@lingual/i18n-check";
379
379
  `checkTranslations` expects the base and comparison or target files and returns an object containing the missing and invalid keys. The optional `options` objects can be provided as a third argument to define the format style via the `format` property, this is useful if you want to validate `i18next` specific translations.
380
380
 
381
381
  ```ts
382
- import { checkTranslations } from "@lingual/i18n-check";
382
+ import { checkTranslations } from '@lingual/i18n-check';
383
383
 
384
384
  const options = {
385
- format: "i18next",
385
+ format: 'i18next',
386
386
  };
387
387
 
388
388
  const { invalidKeys, missingKeys } = checkTranslations(
@@ -395,11 +395,11 @@ const { invalidKeys, missingKeys } = checkTranslations(
395
395
  Additionally the `options` object enables to also define which checks should run via the `checks` property, f.e. if you only want to check for missing or invalid keys only.
396
396
 
397
397
  ```ts
398
- import { checkTranslations } from "@lingual/i18n-check";
398
+ import { checkTranslations } from '@lingual/i18n-check';
399
399
 
400
400
  const options = {
401
- format: "icu",
402
- checks: ["invalidKeys"],
401
+ format: 'icu',
402
+ checks: ['invalidKeys'],
403
403
  };
404
404
 
405
405
  const { invalidKeys } = checkTranslations(source, targets, options);
@@ -433,7 +433,7 @@ The result for `missingKeys` as well as `invalidKeys` is an object containing th
433
433
  `checkMissingTranslations` checks for any missing keys in the target files. All files are compared against the source file.
434
434
 
435
435
  ```ts
436
- import { checkMissingTranslations } from "@lingual/i18n-check";
436
+ import { checkMissingTranslations } from '@lingual/i18n-check';
437
437
 
438
438
  const result = checkMissingTranslations(source, targets);
439
439
 
@@ -450,10 +450,10 @@ The result is an object containing the provided locales and their corresponding
450
450
  `checkInvalidTranslations` checks if there are any invalid keys in the target files. All files are compared against the source file.
451
451
 
452
452
  ```ts
453
- import { checkInvalidTranslations } from "@lingual/i18n-check";
453
+ import { checkInvalidTranslations } from '@lingual/i18n-check';
454
454
 
455
455
  const options = {
456
- format: "i18next",
456
+ format: 'i18next',
457
457
  };
458
458
 
459
459
  const result = checkInvalidTranslations(source, targets, options);
@@ -470,7 +470,7 @@ The result is an object containing the provided locales and their corresponding
470
470
 
471
471
  If you want to checkout and run the code, you need to run the `build` command first.
472
472
 
473
- Run `yarn build`, `pnpm run build` or `npm run build` and then depending on the scenario one of the following commands.
473
+ Run `pnpm run build` and then depending on the scenario one of the following commands.
474
474
 
475
475
  Basic icu translation example:
476
476
 
@@ -516,14 +516,6 @@ To run the tests use one of the following commands:
516
516
  pnpm test
517
517
  ```
518
518
 
519
- ```bash
520
- yarn test
521
- ```
522
-
523
- ```bash
524
- npm test
525
- ```
526
-
527
519
  ## Links
528
520
 
529
521
  - [Introducing i18n-check](https://lingual.dev/blog/introducing-i18n-check/)
package/dist/bin/index.js CHANGED
@@ -14,23 +14,23 @@ const __1 = require("..");
14
14
  const errorReporters_1 = require("../errorReporters");
15
15
  const flattenTranslations_1 = require("../utils/flattenTranslations");
16
16
  const node_path_1 = __importDefault(require("node:path"));
17
- const version = require("../../package.json").version;
17
+ const version = require('../../package.json').version;
18
18
  commander_1.program
19
19
  .version(version)
20
- .option("-l, --locales <locales...>", "name of the directory containing the locales to validate")
21
- .option("-s, --source <locale>", "the source locale to validate against")
22
- .option("-f, --format <type>", "define the specific format: i18next, react-intl or next-intl")
23
- .option("-c, --check <checks...>", "this option is deprecated - use -o or --only instead")
24
- .option("-o, --only <only...>", "define the specific checks you want to run: invalidKeys, missingKeys, unused, undefined. By default the check will validate against missing and invalid keys, i.e. --only invalidKeys,missingKeys")
25
- .option("-r, --reporter <style>", "define the reporting style: standard or summary")
26
- .option("-e, --exclude <exclude...>", "define the file(s) and/or folders(s) that should be excluded from the check")
27
- .option("-u, --unused <paths...>", "define the source path(s) to find all unused and undefined keys")
28
- .option("--parser-component-functions <components...>", "a list of component names to parse when using the --unused option")
20
+ .option('-l, --locales <locales...>', 'name of the directory containing the locales to validate')
21
+ .option('-s, --source <locale>', 'the source locale to validate against')
22
+ .option('-f, --format <type>', 'define the specific format: i18next, react-intl or next-intl')
23
+ .option('-c, --check <checks...>', 'this option is deprecated - use -o or --only instead')
24
+ .option('-o, --only <only...>', 'define the specific checks you want to run: invalidKeys, missingKeys, unused, undefined. By default the check will validate against missing and invalid keys, i.e. --only invalidKeys,missingKeys')
25
+ .option('-r, --reporter <style>', 'define the reporting style: standard or summary')
26
+ .option('-e, --exclude <exclude...>', 'define the file(s) and/or folders(s) that should be excluded from the check')
27
+ .option('-u, --unused <paths...>', 'define the source path(s) to find all unused and undefined keys')
28
+ .option('--parser-component-functions <components...>', 'a list of component names to parse when using the --unused option')
29
29
  .parse();
30
30
  const getCheckOptions = () => {
31
- const checkOption = commander_1.program.getOptionValue("only") || commander_1.program.getOptionValue("check");
32
- if (commander_1.program.getOptionValue("check")) {
33
- console.log(chalk_1.default.yellow("The --check option has been deprecated, use the --only option instead."));
31
+ const checkOption = commander_1.program.getOptionValue('only') || commander_1.program.getOptionValue('check');
32
+ if (commander_1.program.getOptionValue('check')) {
33
+ console.log(chalk_1.default.yellow('The --check option has been deprecated, use the --only option instead.'));
34
34
  }
35
35
  if (!checkOption) {
36
36
  return errorReporters_1.CheckOptions;
@@ -43,33 +43,33 @@ const isSource = (fileInfo, srcPath) => {
43
43
  };
44
44
  const main = async () => {
45
45
  const start = performance.now();
46
- const srcPath = commander_1.program.getOptionValue("source");
47
- const localePath = commander_1.program.getOptionValue("locales");
48
- const format = commander_1.program.getOptionValue("format");
49
- const exclude = commander_1.program.getOptionValue("exclude");
50
- const unusedSrcPath = commander_1.program.getOptionValue("unused");
51
- const componentFunctions = commander_1.program.getOptionValue("parserComponentFunctions");
46
+ const srcPath = commander_1.program.getOptionValue('source');
47
+ const localePath = commander_1.program.getOptionValue('locales');
48
+ const format = commander_1.program.getOptionValue('format');
49
+ const exclude = commander_1.program.getOptionValue('exclude');
50
+ const unusedSrcPath = commander_1.program.getOptionValue('unused');
51
+ const componentFunctions = commander_1.program.getOptionValue('parserComponentFunctions');
52
52
  if (!srcPath) {
53
- console.log(chalk_1.default.red("Source not found. Please provide a valid source locale, i.e. -s en-US"));
53
+ console.log(chalk_1.default.red('Source not found. Please provide a valid source locale, i.e. -s en-US'));
54
54
  (0, node_process_1.exit)(1);
55
55
  }
56
56
  if (!localePath || localePath.length === 0) {
57
- console.log(chalk_1.default.red("Locale file(s) not found. Please provide valid locale file(s), i.e. -locales translations/"));
57
+ console.log(chalk_1.default.red('Locale file(s) not found. Please provide valid locale file(s), i.e. -locales translations/'));
58
58
  (0, node_process_1.exit)(1);
59
59
  }
60
60
  const excludedPaths = exclude ?? [];
61
61
  const localePathFolders = localePath;
62
62
  const isMultiFolders = localePathFolders.length > 1;
63
- let srcFiles = [];
64
- let targetFiles = [];
63
+ const srcFiles = [];
64
+ const targetFiles = [];
65
65
  const pattern = isMultiFolders
66
- ? `{${localePath.join(",").trim()}}/**/*.{json,yaml,yml}`
67
- : `${localePath.join(",").trim()}/**/*.{json,yaml,yml}`;
66
+ ? `{${localePath.join(',').trim()}}/**/*.{json,yaml,yml}`
67
+ : `${localePath.join(',').trim()}/**/*.{json,yaml,yml}`;
68
68
  const files = await (0, glob_1.glob)(pattern, {
69
- ignore: ["node_modules/**"].concat(excludedPaths),
69
+ ignore: ['node_modules/**'].concat(excludedPaths),
70
70
  windowsPathsNoEscape: true,
71
71
  });
72
- console.log("i18n translations checker");
72
+ console.log('i18n translations checker');
73
73
  console.log(chalk_1.default.gray(`Source: ${srcPath}`));
74
74
  if (format) {
75
75
  console.log(chalk_1.default.blackBright(`Selected format is: ${format}`));
@@ -81,8 +81,8 @@ const main = async () => {
81
81
  const fileInfos = [];
82
82
  files.sort().forEach((file) => {
83
83
  const filePath = file.split(node_path_1.default.sep);
84
- const name = filePath.pop() ?? "";
85
- const extension = name.split(".").pop() ?? "json";
84
+ const name = filePath.pop() ?? '';
85
+ const extension = name.split('.').pop() ?? 'json';
86
86
  fileInfos.push({
87
87
  extension,
88
88
  file,
@@ -92,11 +92,11 @@ const main = async () => {
92
92
  });
93
93
  fileInfos.forEach(({ extension, file, name, path }) => {
94
94
  let rawContent;
95
- if (extension === "yaml") {
96
- rawContent = js_yaml_1.default.load(node_fs_1.default.readFileSync(file, "utf-8"));
95
+ if (extension === 'yaml') {
96
+ rawContent = js_yaml_1.default.load(node_fs_1.default.readFileSync(file, 'utf-8'));
97
97
  }
98
98
  else {
99
- rawContent = JSON.parse(node_fs_1.default.readFileSync(file, "utf-8"));
99
+ rawContent = JSON.parse(node_fs_1.default.readFileSync(file, 'utf-8'));
100
100
  }
101
101
  const content = (0, flattenTranslations_1.flattenTranslations)(rawContent);
102
102
  if (isSource({ file, name, path }, srcPath)) {
@@ -107,12 +107,12 @@ const main = async () => {
107
107
  });
108
108
  }
109
109
  else {
110
- const fullPath = path.join("-");
110
+ const fullPath = path.join('-');
111
111
  const reference = fileInfos.find((fileInfo) => {
112
112
  if (!isSource(fileInfo, srcPath)) {
113
113
  return false;
114
114
  }
115
- if (fileInfo.path.join("-") === fullPath) {
115
+ if (fileInfo.path.join('-') === fullPath) {
116
116
  return true;
117
117
  }
118
118
  // Check if the folder path matches - ignoring the last folder
@@ -130,8 +130,8 @@ const main = async () => {
130
130
  //
131
131
  // Referencing: `path/to/locales/en-US/one.json`, `path/to/locales/de-DE/one.json`
132
132
  // Non Referencing: `path/to/locales/en-US/one.json`, `path/to/other/locales/de-DE/one.json`
133
- if (fileInfo.path.slice(0, fileInfo.path.length - 1).join("-") ===
134
- path.slice(0, path.length - 1).join("-")) {
133
+ if (fileInfo.path.slice(0, fileInfo.path.length - 1).join('-') ===
134
+ path.slice(0, path.length - 1).join('-')) {
135
135
  return fileInfo.name === name;
136
136
  }
137
137
  return false;
@@ -146,13 +146,13 @@ const main = async () => {
146
146
  }
147
147
  });
148
148
  if (srcFiles.length === 0) {
149
- console.log(chalk_1.default.red("Source not found. Please provide a valid source locale, i.e. -s en-US"));
149
+ console.log(chalk_1.default.red('Source not found. Please provide a valid source locale, i.e. -s en-US'));
150
150
  (0, node_process_1.exit)(1);
151
151
  }
152
- if ((options.checks.includes("missingKeys") ||
153
- options.checks.includes("invalidKeys")) &&
152
+ if ((options.checks.includes('missingKeys') ||
153
+ options.checks.includes('invalidKeys')) &&
154
154
  targetFiles.length === 0) {
155
- console.log(chalk_1.default.red("Locale file(s) not found. Please provide valid locale file(s), i.e. --locales translations/"));
155
+ console.log(chalk_1.default.red('Locale file(s) not found. Please provide valid locale file(s), i.e. --locales translations/'));
156
156
  (0, node_process_1.exit)(1);
157
157
  }
158
158
  try {
@@ -161,10 +161,10 @@ const main = async () => {
161
161
  if (unusedSrcPath) {
162
162
  const isMultiUnusedFolders = unusedSrcPath.length > 1;
163
163
  const pattern = isMultiUnusedFolders
164
- ? `{${unusedSrcPath.join(",").trim()}}/**/*.{ts,tsx}`
165
- : `${unusedSrcPath.join(",").trim()}/**/*.{ts,tsx}`;
164
+ ? `{${unusedSrcPath.join(',').trim()}}/**/*.{ts,tsx}`
165
+ : `${unusedSrcPath.join(',').trim()}/**/*.{ts,tsx}`;
166
166
  const filesToParse = (0, glob_1.globSync)(pattern, {
167
- ignore: ["node_modules/**"],
167
+ ignore: ['node_modules/**'],
168
168
  windowsPathsNoEscape: true,
169
169
  });
170
170
  const unusedKeys = await (0, __1.checkUnusedKeys)(srcFiles, filesToParse, options, componentFunctions);
@@ -183,6 +183,7 @@ const main = async () => {
183
183
  else {
184
184
  (0, node_process_1.exit)(0);
185
185
  }
186
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
186
187
  }
187
188
  catch (e) {
188
189
  console.log(chalk_1.default.red("\nError: Can't validate translations. Check if the format is supported or specify the translation format i.e. -f i18next"));
@@ -190,10 +191,10 @@ const main = async () => {
190
191
  }
191
192
  };
192
193
  const printTranslationResult = ({ missingKeys, invalidKeys, }) => {
193
- const reporter = commander_1.program.getOptionValue("reporter");
194
- const isSummary = reporter === "summary";
194
+ const reporter = commander_1.program.getOptionValue('reporter');
195
+ const isSummary = reporter === 'summary';
195
196
  if (missingKeys && Object.keys(missingKeys).length > 0) {
196
- console.log(chalk_1.default.red("\nFound missing keys!"));
197
+ console.log(chalk_1.default.red('\nFound missing keys!'));
197
198
  if (isSummary) {
198
199
  console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(missingKeys)));
199
200
  }
@@ -203,10 +204,10 @@ const printTranslationResult = ({ missingKeys, invalidKeys, }) => {
203
204
  }
204
205
  }
205
206
  else if (missingKeys) {
206
- console.log(chalk_1.default.green("\nNo missing keys found!"));
207
+ console.log(chalk_1.default.green('\nNo missing keys found!'));
207
208
  }
208
209
  if (invalidKeys && Object.keys(invalidKeys).length > 0) {
209
- console.log(chalk_1.default.red("\nFound invalid keys!"));
210
+ console.log(chalk_1.default.red('\nFound invalid keys!'));
210
211
  if (isSummary) {
211
212
  console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(invalidKeys)));
212
213
  }
@@ -216,14 +217,14 @@ const printTranslationResult = ({ missingKeys, invalidKeys, }) => {
216
217
  }
217
218
  }
218
219
  else if (invalidKeys) {
219
- console.log(chalk_1.default.green("\nNo invalid translations found!"));
220
+ console.log(chalk_1.default.green('\nNo invalid translations found!'));
220
221
  }
221
222
  };
222
223
  const printUnusedKeysResult = ({ unusedKeys, }) => {
223
- const reporter = commander_1.program.getOptionValue("reporter");
224
- const isSummary = reporter === "summary";
224
+ const reporter = commander_1.program.getOptionValue('reporter');
225
+ const isSummary = reporter === 'summary';
225
226
  if (unusedKeys && hasKeys(unusedKeys)) {
226
- console.log(chalk_1.default.red("\nFound unused keys!"));
227
+ console.log(chalk_1.default.red('\nFound unused keys!'));
227
228
  if (isSummary) {
228
229
  console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(unusedKeys)));
229
230
  }
@@ -232,14 +233,14 @@ const printUnusedKeysResult = ({ unusedKeys, }) => {
232
233
  }
233
234
  }
234
235
  else if (unusedKeys) {
235
- console.log(chalk_1.default.green("\nNo unused keys found!"));
236
+ console.log(chalk_1.default.green('\nNo unused keys found!'));
236
237
  }
237
238
  };
238
239
  const printUndefinedKeysResult = ({ undefinedKeys, }) => {
239
- const reporter = commander_1.program.getOptionValue("reporter");
240
- const isSummary = reporter === "summary";
240
+ const reporter = commander_1.program.getOptionValue('reporter');
241
+ const isSummary = reporter === 'summary';
241
242
  if (undefinedKeys && hasKeys(undefinedKeys)) {
242
- console.log(chalk_1.default.red("\nFound undefined keys!"));
243
+ console.log(chalk_1.default.red('\nFound undefined keys!'));
243
244
  if (isSummary) {
244
245
  console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(undefinedKeys)));
245
246
  }
@@ -248,7 +249,7 @@ const printUndefinedKeysResult = ({ undefinedKeys, }) => {
248
249
  }
249
250
  }
250
251
  else if (undefinedKeys) {
251
- console.log(chalk_1.default.green("\nNo undefined keys found!"));
252
+ console.log(chalk_1.default.green('\nNo undefined keys found!'));
252
253
  }
253
254
  };
254
255
  const hasKeys = (checkResult) => {