@lingual/i18n-check 0.8.1 → 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 +10 -18
- package/dist/bin/index.js +73 -99
- package/dist/bin/index.test.js +560 -472
- package/dist/errorReporters.d.ts +5 -7
- package/dist/errorReporters.js +67 -81
- package/dist/errorReporters.test.d.ts +1 -0
- package/dist/errorReporters.test.js +165 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +78 -54
- package/dist/types.d.ts +5 -0
- package/dist/utils/findInvalidTranslations.d.ts +4 -7
- package/dist/utils/findInvalidTranslations.js +23 -22
- package/dist/utils/findInvalidTranslations.test.js +30 -30
- package/dist/utils/findInvalidi18nTranslations.d.ts +4 -4
- package/dist/utils/findInvalidi18nTranslations.js +36 -36
- package/dist/utils/findInvalidi18nTranslations.test.js +72 -72
- package/dist/utils/findMissingKeys.d.ts +2 -2
- package/dist/utils/findMissingKeys.js +3 -3
- package/dist/utils/findMissingKeys.test.js +20 -20
- package/dist/utils/flattenTranslations.d.ts +1 -1
- package/dist/utils/flattenTranslations.js +4 -4
- package/dist/utils/flattenTranslations.test.js +13 -13
- package/dist/utils/i18NextParser.d.ts +6 -6
- package/dist/utils/i18NextParser.js +29 -29
- package/dist/utils/i18NextParser.test.js +104 -104
- package/dist/utils/nextIntlSrcParser.js +11 -11
- package/dist/utils/nextIntlSrcParser.test.js +206 -206
- package/package.json +14 -4
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
|
|
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
|
|
382
|
+
import { checkTranslations } from '@lingual/i18n-check';
|
|
383
383
|
|
|
384
384
|
const options = {
|
|
385
|
-
format:
|
|
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
|
|
398
|
+
import { checkTranslations } from '@lingual/i18n-check';
|
|
399
399
|
|
|
400
400
|
const options = {
|
|
401
|
-
format:
|
|
402
|
-
checks: [
|
|
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
|
|
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
|
|
453
|
+
import { checkInvalidTranslations } from '@lingual/i18n-check';
|
|
454
454
|
|
|
455
455
|
const options = {
|
|
456
|
-
format:
|
|
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 `
|
|
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
|
@@ -13,23 +13,24 @@ const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
|
13
13
|
const __1 = require("..");
|
|
14
14
|
const errorReporters_1 = require("../errorReporters");
|
|
15
15
|
const flattenTranslations_1 = require("../utils/flattenTranslations");
|
|
16
|
-
const
|
|
16
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
+
const version = require('../../package.json').version;
|
|
17
18
|
commander_1.program
|
|
18
19
|
.version(version)
|
|
19
|
-
.option(
|
|
20
|
-
.option(
|
|
21
|
-
.option(
|
|
22
|
-
.option(
|
|
23
|
-
.option(
|
|
24
|
-
.option(
|
|
25
|
-
.option(
|
|
26
|
-
.option(
|
|
27
|
-
.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')
|
|
28
29
|
.parse();
|
|
29
30
|
const getCheckOptions = () => {
|
|
30
|
-
const checkOption = commander_1.program.getOptionValue(
|
|
31
|
-
if (commander_1.program.getOptionValue(
|
|
32
|
-
console.log(chalk_1.default.yellow(
|
|
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.'));
|
|
33
34
|
}
|
|
34
35
|
if (!checkOption) {
|
|
35
36
|
return errorReporters_1.CheckOptions;
|
|
@@ -42,32 +43,33 @@ const isSource = (fileInfo, srcPath) => {
|
|
|
42
43
|
};
|
|
43
44
|
const main = async () => {
|
|
44
45
|
const start = performance.now();
|
|
45
|
-
const srcPath = commander_1.program.getOptionValue(
|
|
46
|
-
const localePath = commander_1.program.getOptionValue(
|
|
47
|
-
const format = commander_1.program.getOptionValue(
|
|
48
|
-
const exclude = commander_1.program.getOptionValue(
|
|
49
|
-
const unusedSrcPath = commander_1.program.getOptionValue(
|
|
50
|
-
const componentFunctions = commander_1.program.getOptionValue(
|
|
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');
|
|
51
52
|
if (!srcPath) {
|
|
52
|
-
console.log(chalk_1.default.red(
|
|
53
|
+
console.log(chalk_1.default.red('Source not found. Please provide a valid source locale, i.e. -s en-US'));
|
|
53
54
|
(0, node_process_1.exit)(1);
|
|
54
55
|
}
|
|
55
56
|
if (!localePath || localePath.length === 0) {
|
|
56
|
-
console.log(chalk_1.default.red(
|
|
57
|
+
console.log(chalk_1.default.red('Locale file(s) not found. Please provide valid locale file(s), i.e. -locales translations/'));
|
|
57
58
|
(0, node_process_1.exit)(1);
|
|
58
59
|
}
|
|
59
60
|
const excludedPaths = exclude ?? [];
|
|
60
61
|
const localePathFolders = localePath;
|
|
61
62
|
const isMultiFolders = localePathFolders.length > 1;
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
const srcFiles = [];
|
|
64
|
+
const targetFiles = [];
|
|
64
65
|
const pattern = isMultiFolders
|
|
65
|
-
? `{${localePath.join(
|
|
66
|
-
: `${localePath.join(
|
|
66
|
+
? `{${localePath.join(',').trim()}}/**/*.{json,yaml,yml}`
|
|
67
|
+
: `${localePath.join(',').trim()}/**/*.{json,yaml,yml}`;
|
|
67
68
|
const files = await (0, glob_1.glob)(pattern, {
|
|
68
|
-
ignore: [
|
|
69
|
+
ignore: ['node_modules/**'].concat(excludedPaths),
|
|
70
|
+
windowsPathsNoEscape: true,
|
|
69
71
|
});
|
|
70
|
-
console.log(
|
|
72
|
+
console.log('i18n translations checker');
|
|
71
73
|
console.log(chalk_1.default.gray(`Source: ${srcPath}`));
|
|
72
74
|
if (format) {
|
|
73
75
|
console.log(chalk_1.default.blackBright(`Selected format is: ${format}`));
|
|
@@ -78,23 +80,23 @@ const main = async () => {
|
|
|
78
80
|
};
|
|
79
81
|
const fileInfos = [];
|
|
80
82
|
files.sort().forEach((file) => {
|
|
81
|
-
const
|
|
82
|
-
const name =
|
|
83
|
-
const extension = name.split(
|
|
83
|
+
const filePath = file.split(node_path_1.default.sep);
|
|
84
|
+
const name = filePath.pop() ?? '';
|
|
85
|
+
const extension = name.split('.').pop() ?? 'json';
|
|
84
86
|
fileInfos.push({
|
|
85
87
|
extension,
|
|
86
88
|
file,
|
|
87
89
|
name,
|
|
88
|
-
path,
|
|
90
|
+
path: filePath,
|
|
89
91
|
});
|
|
90
92
|
});
|
|
91
93
|
fileInfos.forEach(({ extension, file, name, path }) => {
|
|
92
94
|
let rawContent;
|
|
93
|
-
if (extension ===
|
|
94
|
-
rawContent = js_yaml_1.default.load(node_fs_1.default.readFileSync(file,
|
|
95
|
+
if (extension === 'yaml') {
|
|
96
|
+
rawContent = js_yaml_1.default.load(node_fs_1.default.readFileSync(file, 'utf-8'));
|
|
95
97
|
}
|
|
96
98
|
else {
|
|
97
|
-
rawContent = JSON.parse(node_fs_1.default.readFileSync(file,
|
|
99
|
+
rawContent = JSON.parse(node_fs_1.default.readFileSync(file, 'utf-8'));
|
|
98
100
|
}
|
|
99
101
|
const content = (0, flattenTranslations_1.flattenTranslations)(rawContent);
|
|
100
102
|
if (isSource({ file, name, path }, srcPath)) {
|
|
@@ -105,12 +107,12 @@ const main = async () => {
|
|
|
105
107
|
});
|
|
106
108
|
}
|
|
107
109
|
else {
|
|
108
|
-
const fullPath = path.join(
|
|
110
|
+
const fullPath = path.join('-');
|
|
109
111
|
const reference = fileInfos.find((fileInfo) => {
|
|
110
112
|
if (!isSource(fileInfo, srcPath)) {
|
|
111
113
|
return false;
|
|
112
114
|
}
|
|
113
|
-
if (fileInfo.path.join(
|
|
115
|
+
if (fileInfo.path.join('-') === fullPath) {
|
|
114
116
|
return true;
|
|
115
117
|
}
|
|
116
118
|
// Check if the folder path matches - ignoring the last folder
|
|
@@ -128,8 +130,8 @@ const main = async () => {
|
|
|
128
130
|
//
|
|
129
131
|
// Referencing: `path/to/locales/en-US/one.json`, `path/to/locales/de-DE/one.json`
|
|
130
132
|
// Non Referencing: `path/to/locales/en-US/one.json`, `path/to/other/locales/de-DE/one.json`
|
|
131
|
-
if (fileInfo.path.slice(0, fileInfo.path.length - 1).join(
|
|
132
|
-
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('-')) {
|
|
133
135
|
return fileInfo.name === name;
|
|
134
136
|
}
|
|
135
137
|
return false;
|
|
@@ -144,13 +146,13 @@ const main = async () => {
|
|
|
144
146
|
}
|
|
145
147
|
});
|
|
146
148
|
if (srcFiles.length === 0) {
|
|
147
|
-
console.log(chalk_1.default.red(
|
|
149
|
+
console.log(chalk_1.default.red('Source not found. Please provide a valid source locale, i.e. -s en-US'));
|
|
148
150
|
(0, node_process_1.exit)(1);
|
|
149
151
|
}
|
|
150
|
-
if ((options.checks.includes(
|
|
151
|
-
options.checks.includes(
|
|
152
|
+
if ((options.checks.includes('missingKeys') ||
|
|
153
|
+
options.checks.includes('invalidKeys')) &&
|
|
152
154
|
targetFiles.length === 0) {
|
|
153
|
-
console.log(chalk_1.default.red(
|
|
155
|
+
console.log(chalk_1.default.red('Locale file(s) not found. Please provide valid locale file(s), i.e. --locales translations/'));
|
|
154
156
|
(0, node_process_1.exit)(1);
|
|
155
157
|
}
|
|
156
158
|
try {
|
|
@@ -159,10 +161,11 @@ const main = async () => {
|
|
|
159
161
|
if (unusedSrcPath) {
|
|
160
162
|
const isMultiUnusedFolders = unusedSrcPath.length > 1;
|
|
161
163
|
const pattern = isMultiUnusedFolders
|
|
162
|
-
? `{${unusedSrcPath.join(
|
|
163
|
-
: `${unusedSrcPath.join(
|
|
164
|
+
? `{${unusedSrcPath.join(',').trim()}}/**/*.{ts,tsx}`
|
|
165
|
+
: `${unusedSrcPath.join(',').trim()}/**/*.{ts,tsx}`;
|
|
164
166
|
const filesToParse = (0, glob_1.globSync)(pattern, {
|
|
165
|
-
ignore: [
|
|
167
|
+
ignore: ['node_modules/**'],
|
|
168
|
+
windowsPathsNoEscape: true,
|
|
166
169
|
});
|
|
167
170
|
const unusedKeys = await (0, __1.checkUnusedKeys)(srcFiles, filesToParse, options, componentFunctions);
|
|
168
171
|
printUnusedKeysResult({ unusedKeys });
|
|
@@ -180,6 +183,7 @@ const main = async () => {
|
|
|
180
183
|
else {
|
|
181
184
|
(0, node_process_1.exit)(0);
|
|
182
185
|
}
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
183
187
|
}
|
|
184
188
|
catch (e) {
|
|
185
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"));
|
|
@@ -187,97 +191,67 @@ const main = async () => {
|
|
|
187
191
|
}
|
|
188
192
|
};
|
|
189
193
|
const printTranslationResult = ({ missingKeys, invalidKeys, }) => {
|
|
190
|
-
const reporter = commander_1.program.getOptionValue(
|
|
191
|
-
const isSummary = reporter ===
|
|
194
|
+
const reporter = commander_1.program.getOptionValue('reporter');
|
|
195
|
+
const isSummary = reporter === 'summary';
|
|
192
196
|
if (missingKeys && Object.keys(missingKeys).length > 0) {
|
|
193
|
-
console.log(chalk_1.default.red(
|
|
197
|
+
console.log(chalk_1.default.red('\nFound missing keys!'));
|
|
194
198
|
if (isSummary) {
|
|
195
|
-
console.log(chalk_1.default.red((0, errorReporters_1.
|
|
199
|
+
console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(missingKeys)));
|
|
196
200
|
}
|
|
197
201
|
else {
|
|
198
|
-
|
|
202
|
+
const table = (0, errorReporters_1.formatCheckResultTable)(missingKeys);
|
|
203
|
+
console.log(chalk_1.default.red(table));
|
|
199
204
|
}
|
|
200
205
|
}
|
|
201
206
|
else if (missingKeys) {
|
|
202
|
-
console.log(chalk_1.default.green(
|
|
207
|
+
console.log(chalk_1.default.green('\nNo missing keys found!'));
|
|
203
208
|
}
|
|
204
209
|
if (invalidKeys && Object.keys(invalidKeys).length > 0) {
|
|
205
|
-
console.log(chalk_1.default.red(
|
|
210
|
+
console.log(chalk_1.default.red('\nFound invalid keys!'));
|
|
206
211
|
if (isSummary) {
|
|
207
|
-
console.log(chalk_1.default.red((0, errorReporters_1.
|
|
212
|
+
console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(invalidKeys)));
|
|
208
213
|
}
|
|
209
214
|
else {
|
|
210
|
-
|
|
215
|
+
const table = (0, errorReporters_1.formatInvalidTranslationsResultTable)(invalidKeys);
|
|
216
|
+
console.log(chalk_1.default.red(table));
|
|
211
217
|
}
|
|
212
218
|
}
|
|
213
219
|
else if (invalidKeys) {
|
|
214
|
-
console.log(chalk_1.default.green(
|
|
220
|
+
console.log(chalk_1.default.green('\nNo invalid translations found!'));
|
|
215
221
|
}
|
|
216
222
|
};
|
|
217
223
|
const printUnusedKeysResult = ({ unusedKeys, }) => {
|
|
218
|
-
const reporter = commander_1.program.getOptionValue(
|
|
219
|
-
const isSummary = reporter ===
|
|
224
|
+
const reporter = commander_1.program.getOptionValue('reporter');
|
|
225
|
+
const isSummary = reporter === 'summary';
|
|
220
226
|
if (unusedKeys && hasKeys(unusedKeys)) {
|
|
221
|
-
console.log(chalk_1.default.red(
|
|
227
|
+
console.log(chalk_1.default.red('\nFound unused keys!'));
|
|
222
228
|
if (isSummary) {
|
|
223
|
-
console.log(chalk_1.default.red((0, errorReporters_1.
|
|
229
|
+
console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(unusedKeys)));
|
|
224
230
|
}
|
|
225
231
|
else {
|
|
226
|
-
console.log(chalk_1.default.red((0, errorReporters_1.
|
|
232
|
+
console.log(chalk_1.default.red((0, errorReporters_1.formatCheckResultTable)(unusedKeys)));
|
|
227
233
|
}
|
|
228
234
|
}
|
|
229
235
|
else if (unusedKeys) {
|
|
230
|
-
console.log(chalk_1.default.green(
|
|
236
|
+
console.log(chalk_1.default.green('\nNo unused keys found!'));
|
|
231
237
|
}
|
|
232
238
|
};
|
|
233
239
|
const printUndefinedKeysResult = ({ undefinedKeys, }) => {
|
|
234
|
-
const reporter = commander_1.program.getOptionValue(
|
|
235
|
-
const isSummary = reporter ===
|
|
240
|
+
const reporter = commander_1.program.getOptionValue('reporter');
|
|
241
|
+
const isSummary = reporter === 'summary';
|
|
236
242
|
if (undefinedKeys && hasKeys(undefinedKeys)) {
|
|
237
|
-
console.log(chalk_1.default.red(
|
|
243
|
+
console.log(chalk_1.default.red('\nFound undefined keys!'));
|
|
238
244
|
if (isSummary) {
|
|
239
|
-
console.log(chalk_1.default.red((0, errorReporters_1.
|
|
245
|
+
console.log(chalk_1.default.red((0, errorReporters_1.formatSummaryTable)(undefinedKeys)));
|
|
240
246
|
}
|
|
241
247
|
else {
|
|
242
|
-
console.log(chalk_1.default.red((0, errorReporters_1.
|
|
248
|
+
console.log(chalk_1.default.red((0, errorReporters_1.formatCheckResultTable)(undefinedKeys)));
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
251
|
else if (undefinedKeys) {
|
|
246
|
-
console.log(chalk_1.default.green(
|
|
252
|
+
console.log(chalk_1.default.green('\nNo undefined keys found!'));
|
|
247
253
|
}
|
|
248
254
|
};
|
|
249
|
-
const truncate = (chars, len = 80) => chars.length > 80 ? `${chars.substring(0, len)}...` : chars;
|
|
250
|
-
const getSummaryRows = (checkResult) => {
|
|
251
|
-
const formattedRows = [];
|
|
252
|
-
for (const [file, keys] of Object.entries(checkResult)) {
|
|
253
|
-
formattedRows.push({
|
|
254
|
-
file: truncate(file),
|
|
255
|
-
total: keys.length,
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
return formattedRows;
|
|
259
|
-
};
|
|
260
|
-
const getStandardRows = (checkResult) => {
|
|
261
|
-
const formattedRows = [];
|
|
262
|
-
for (const [file, keys] of Object.entries(checkResult)) {
|
|
263
|
-
for (const entry of keys) {
|
|
264
|
-
if (typeof entry === "object") {
|
|
265
|
-
formattedRows.push({
|
|
266
|
-
file: truncate(file),
|
|
267
|
-
key: truncate(entry.key),
|
|
268
|
-
msg: truncate(entry.msg, 120),
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
formattedRows.push({
|
|
273
|
-
file: truncate(file),
|
|
274
|
-
key: truncate(entry),
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
return formattedRows;
|
|
280
|
-
};
|
|
281
255
|
const hasKeys = (checkResult) => {
|
|
282
256
|
for (const [_, keys] of Object.entries(checkResult)) {
|
|
283
257
|
if (keys.length > 0) {
|