@lingual/i18n-check 0.8.2 → 0.8.4
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 +32 -18
- package/dist/bin/index.js +61 -57
- package/dist/bin/index.test.js +321 -289
- package/dist/errorReporters.d.ts +1 -1
- package/dist/errorReporters.js +21 -21
- package/dist/errorReporters.test.js +39 -39
- package/dist/index.d.ts +4 -3
- package/dist/index.js +82 -47
- package/dist/utils/findInvalidTranslations.d.ts +2 -2
- package/dist/utils/findInvalidTranslations.js +20 -19
- package/dist/utils/findInvalidTranslations.test.js +30 -30
- package/dist/utils/findInvalidi18nTranslations.d.ts +2 -2
- package/dist/utils/findInvalidi18nTranslations.js +35 -35
- package/dist/utils/findInvalidi18nTranslations.test.js +72 -72
- package/dist/utils/findMissingKeys.d.ts +1 -1
- package/dist/utils/findMissingKeys.js +2 -2
- package/dist/utils/findMissingKeys.test.js +20 -20
- package/dist/utils/flattenTranslations.d.ts +1 -1
- package/dist/utils/flattenTranslations.js +3 -3
- 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 +156 -156
- package/package.json +14 -4
|
@@ -1,150 +1,150 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const i18NextParser_1 = require("./i18NextParser");
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
6
|
-
expect((0, i18NextParser_1.parse)(
|
|
4
|
+
describe('i18NextParser', () => {
|
|
5
|
+
it('should parse interpolation', () => {
|
|
6
|
+
expect((0, i18NextParser_1.parse)('test {{val}} text {{- encoded}} with {{val, format}} some $t{nesting} help')).toEqual([
|
|
7
7
|
{
|
|
8
|
-
type:
|
|
9
|
-
content:
|
|
8
|
+
type: 'text',
|
|
9
|
+
content: 'test ',
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
|
-
type:
|
|
13
|
-
raw:
|
|
14
|
-
prefix:
|
|
15
|
-
suffix:
|
|
16
|
-
content:
|
|
17
|
-
variable:
|
|
12
|
+
type: 'interpolation',
|
|
13
|
+
raw: '{{val}}',
|
|
14
|
+
prefix: '{{',
|
|
15
|
+
suffix: '}}',
|
|
16
|
+
content: 'val',
|
|
17
|
+
variable: 'val',
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
type:
|
|
21
|
-
content:
|
|
20
|
+
type: 'text',
|
|
21
|
+
content: ' text ',
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
type:
|
|
25
|
-
raw:
|
|
26
|
-
prefix:
|
|
27
|
-
suffix:
|
|
28
|
-
content:
|
|
29
|
-
variable:
|
|
24
|
+
type: 'interpolation_unescaped',
|
|
25
|
+
raw: '{{- encoded}}',
|
|
26
|
+
prefix: '{{-',
|
|
27
|
+
suffix: '}}',
|
|
28
|
+
content: ' encoded',
|
|
29
|
+
variable: 'encoded',
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
|
-
type:
|
|
33
|
-
content:
|
|
32
|
+
type: 'text',
|
|
33
|
+
content: ' with ',
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
type:
|
|
37
|
-
raw:
|
|
38
|
-
prefix:
|
|
39
|
-
suffix:
|
|
40
|
-
content:
|
|
41
|
-
variable:
|
|
36
|
+
type: 'interpolation',
|
|
37
|
+
raw: '{{val, format}}',
|
|
38
|
+
prefix: '{{',
|
|
39
|
+
suffix: '}}',
|
|
40
|
+
content: 'val, format',
|
|
41
|
+
variable: 'val, format',
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
type:
|
|
45
|
-
content:
|
|
44
|
+
type: 'text',
|
|
45
|
+
content: ' some ',
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
|
-
type:
|
|
49
|
-
raw:
|
|
50
|
-
prefix:
|
|
51
|
-
suffix:
|
|
52
|
-
content:
|
|
53
|
-
variable:
|
|
48
|
+
type: 'nesting',
|
|
49
|
+
raw: '$t{nesting}',
|
|
50
|
+
prefix: '$t{',
|
|
51
|
+
suffix: '}',
|
|
52
|
+
content: 'nesting',
|
|
53
|
+
variable: 'nesting',
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
type:
|
|
57
|
-
content:
|
|
56
|
+
type: 'text',
|
|
57
|
+
content: ' help',
|
|
58
58
|
},
|
|
59
59
|
]);
|
|
60
60
|
});
|
|
61
|
-
it(
|
|
62
|
-
expect((0, i18NextParser_1.parse)(
|
|
61
|
+
it('should parse plural translations', () => {
|
|
62
|
+
expect((0, i18NextParser_1.parse)('(1)[one item];(2-7)[a few items];(7-inf)[a lot of items];')).toEqual([
|
|
63
63
|
{
|
|
64
|
-
type:
|
|
65
|
-
raw:
|
|
66
|
-
prefix:
|
|
67
|
-
suffix:
|
|
68
|
-
content:
|
|
69
|
-
variable:
|
|
64
|
+
type: 'plural',
|
|
65
|
+
raw: '(1)',
|
|
66
|
+
prefix: '(',
|
|
67
|
+
suffix: ')',
|
|
68
|
+
content: '1',
|
|
69
|
+
variable: '1',
|
|
70
70
|
},
|
|
71
|
-
{ type:
|
|
71
|
+
{ type: 'text', content: '[one item];' },
|
|
72
72
|
{
|
|
73
|
-
type:
|
|
74
|
-
raw:
|
|
75
|
-
prefix:
|
|
76
|
-
suffix:
|
|
77
|
-
content:
|
|
78
|
-
variable:
|
|
73
|
+
type: 'plural',
|
|
74
|
+
raw: '(2-7)',
|
|
75
|
+
prefix: '(',
|
|
76
|
+
suffix: ')',
|
|
77
|
+
content: '2-7',
|
|
78
|
+
variable: '2-7',
|
|
79
79
|
},
|
|
80
|
-
{ type:
|
|
80
|
+
{ type: 'text', content: '[a few items];' },
|
|
81
81
|
{
|
|
82
|
-
type:
|
|
83
|
-
raw:
|
|
84
|
-
prefix:
|
|
85
|
-
suffix:
|
|
86
|
-
content:
|
|
87
|
-
variable:
|
|
82
|
+
type: 'plural',
|
|
83
|
+
raw: '(7-inf)',
|
|
84
|
+
prefix: '(',
|
|
85
|
+
suffix: ')',
|
|
86
|
+
content: '7-inf',
|
|
87
|
+
variable: '7-inf',
|
|
88
88
|
},
|
|
89
|
-
{ type:
|
|
89
|
+
{ type: 'text', content: '[a lot of items];' },
|
|
90
90
|
]);
|
|
91
91
|
});
|
|
92
|
-
it(
|
|
93
|
-
expect((0, i18NextParser_1.parse)(
|
|
94
|
-
{ type:
|
|
92
|
+
it('should not parse plural translations if regular text inside parenthesis', () => {
|
|
93
|
+
expect((0, i18NextParser_1.parse)('(This is a regular text inside parenthesis)')).toEqual([
|
|
94
|
+
{ type: 'text', content: '(This is a regular text inside parenthesis)' },
|
|
95
95
|
]);
|
|
96
96
|
});
|
|
97
|
-
it(
|
|
98
|
-
expect((0, i18NextParser_1.parse)(
|
|
97
|
+
it('should parse translations with nesting', () => {
|
|
98
|
+
expect((0, i18NextParser_1.parse)('1 $t(nesting2)')).toEqual([
|
|
99
99
|
{
|
|
100
|
-
type:
|
|
101
|
-
content:
|
|
100
|
+
type: 'text',
|
|
101
|
+
content: '1 ',
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
|
-
type:
|
|
105
|
-
raw:
|
|
106
|
-
prefix:
|
|
107
|
-
suffix:
|
|
108
|
-
content:
|
|
109
|
-
variable:
|
|
104
|
+
type: 'nesting',
|
|
105
|
+
raw: '$t(nesting2)',
|
|
106
|
+
prefix: '$t(',
|
|
107
|
+
suffix: ')',
|
|
108
|
+
content: 'nesting2',
|
|
109
|
+
variable: 'nesting2',
|
|
110
110
|
},
|
|
111
111
|
]);
|
|
112
112
|
});
|
|
113
|
-
it(
|
|
114
|
-
expect((0, i18NextParser_1.parse)(
|
|
115
|
-
{ type:
|
|
116
|
-
{ type:
|
|
117
|
-
{ type:
|
|
118
|
-
{ type:
|
|
119
|
-
{ type:
|
|
120
|
-
{ type:
|
|
121
|
-
{ type:
|
|
122
|
-
{ type:
|
|
123
|
-
{ type:
|
|
113
|
+
it('should parse translations with tags', () => {
|
|
114
|
+
expect((0, i18NextParser_1.parse)('This is some <b>bold text</b> and some <i>italic</i> text.')).toEqual([
|
|
115
|
+
{ type: 'text', content: 'This is some ' },
|
|
116
|
+
{ type: 'tag', raw: '<b>', voidElement: false },
|
|
117
|
+
{ type: 'text', content: 'bold text' },
|
|
118
|
+
{ type: 'tag', raw: '</b>', voidElement: false },
|
|
119
|
+
{ type: 'text', content: ' and some ' },
|
|
120
|
+
{ type: 'tag', raw: '<i>', voidElement: false },
|
|
121
|
+
{ type: 'text', content: 'italic' },
|
|
122
|
+
{ type: 'tag', raw: '</i>', voidElement: false },
|
|
123
|
+
{ type: 'text', content: ' text.' },
|
|
124
124
|
]);
|
|
125
125
|
});
|
|
126
|
-
it(
|
|
127
|
-
expect((0, i18NextParser_1.parse)(
|
|
128
|
-
{ type:
|
|
129
|
-
{ type:
|
|
130
|
-
{ type:
|
|
131
|
-
{ type:
|
|
132
|
-
{ type:
|
|
133
|
-
{ type:
|
|
134
|
-
{ type:
|
|
135
|
-
{ type:
|
|
136
|
-
{ type:
|
|
126
|
+
it('should parse translations with nested tags', () => {
|
|
127
|
+
expect((0, i18NextParser_1.parse)('This is some <b>bold text and some <i>nested italic</i> text</b>!')).toEqual([
|
|
128
|
+
{ type: 'text', content: 'This is some ' },
|
|
129
|
+
{ type: 'tag', raw: '<b>', voidElement: false },
|
|
130
|
+
{ type: 'text', content: 'bold text and some ' },
|
|
131
|
+
{ type: 'tag', raw: '<i>', voidElement: false },
|
|
132
|
+
{ type: 'text', content: 'nested italic' },
|
|
133
|
+
{ type: 'tag', raw: '</i>', voidElement: false },
|
|
134
|
+
{ type: 'text', content: ' text' },
|
|
135
|
+
{ type: 'tag', raw: '</b>', voidElement: false },
|
|
136
|
+
{ type: 'text', content: '!' },
|
|
137
137
|
]);
|
|
138
138
|
});
|
|
139
|
-
it(
|
|
140
|
-
expect((0, i18NextParser_1.parse)(
|
|
141
|
-
{ type:
|
|
142
|
-
{ type:
|
|
143
|
-
{ type:
|
|
144
|
-
{ type:
|
|
145
|
-
{ type:
|
|
146
|
-
{ type:
|
|
147
|
-
{ type:
|
|
139
|
+
it('should parse translations with self closing tags', () => {
|
|
140
|
+
expect((0, i18NextParser_1.parse)('This is some <b>bold text and some </b> and some random self closing tag <img /> as well.')).toEqual([
|
|
141
|
+
{ type: 'text', content: 'This is some ' },
|
|
142
|
+
{ type: 'tag', raw: '<b>', voidElement: false },
|
|
143
|
+
{ type: 'text', content: 'bold text and some ' },
|
|
144
|
+
{ type: 'tag', raw: '</b>', voidElement: false },
|
|
145
|
+
{ type: 'text', content: ' and some random self closing tag ' },
|
|
146
|
+
{ type: 'tag', raw: '<img />', voidElement: true },
|
|
147
|
+
{ type: 'text', content: ' as well.' },
|
|
148
148
|
]);
|
|
149
149
|
});
|
|
150
150
|
});
|
|
@@ -39,8 +39,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.extract = void 0;
|
|
40
40
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
41
|
const ts = __importStar(require("typescript"));
|
|
42
|
-
const USE_TRANSLATIONS =
|
|
43
|
-
const GET_TRANSLATIONS =
|
|
42
|
+
const USE_TRANSLATIONS = 'useTranslations';
|
|
43
|
+
const GET_TRANSLATIONS = 'getTranslations';
|
|
44
44
|
const COMMENT_CONTAINS_STATIC_KEY_REGEX = /t\((["'])(.*?[^\\])(["'])\)/;
|
|
45
45
|
const extract = (filesPaths) => {
|
|
46
46
|
return filesPaths.flatMap(getKeys).sort((a, b) => {
|
|
@@ -49,7 +49,7 @@ const extract = (filesPaths) => {
|
|
|
49
49
|
};
|
|
50
50
|
exports.extract = extract;
|
|
51
51
|
const getKeys = (path) => {
|
|
52
|
-
const content = node_fs_1.default.readFileSync(path,
|
|
52
|
+
const content = node_fs_1.default.readFileSync(path, 'utf-8');
|
|
53
53
|
const sourceFile = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
|
|
54
54
|
const foundKeys = [];
|
|
55
55
|
let namespaces = [];
|
|
@@ -82,7 +82,7 @@ const getKeys = (path) => {
|
|
|
82
82
|
};
|
|
83
83
|
const visit = (node) => {
|
|
84
84
|
let key = null;
|
|
85
|
-
|
|
85
|
+
const initialNamespacesLength = namespaces.length;
|
|
86
86
|
if (node === undefined) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
@@ -94,12 +94,12 @@ const getKeys = (path) => {
|
|
|
94
94
|
// from the default `t`, i.e.: const other = useTranslations("namespace1");
|
|
95
95
|
if (node.initializer.expression.text === USE_TRANSLATIONS) {
|
|
96
96
|
const [argument] = node.initializer.arguments;
|
|
97
|
-
const variable = ts.isIdentifier(node.name) ? node.name.text :
|
|
97
|
+
const variable = ts.isIdentifier(node.name) ? node.name.text : 't';
|
|
98
98
|
if (argument && ts.isStringLiteral(argument)) {
|
|
99
99
|
pushNamespace({ name: argument.text, variable });
|
|
100
100
|
}
|
|
101
101
|
else if (argument === undefined) {
|
|
102
|
-
pushNamespace({ name:
|
|
102
|
+
pushNamespace({ name: '', variable });
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -119,14 +119,14 @@ const getKeys = (path) => {
|
|
|
119
119
|
ts.isIdentifier(node.initializer.expression.expression)) {
|
|
120
120
|
if (node.initializer.expression.expression.text === GET_TRANSLATIONS) {
|
|
121
121
|
const [argument] = node.initializer.expression.arguments;
|
|
122
|
-
const variable = ts.isIdentifier(node.name) ? node.name.text :
|
|
122
|
+
const variable = ts.isIdentifier(node.name) ? node.name.text : 't';
|
|
123
123
|
if (argument && ts.isObjectLiteralExpression(argument)) {
|
|
124
124
|
argument.properties.forEach((property) => {
|
|
125
125
|
if (property &&
|
|
126
126
|
ts.isPropertyAssignment(property) &&
|
|
127
127
|
property.name &&
|
|
128
128
|
ts.isIdentifier(property.name) &&
|
|
129
|
-
property.name.text ===
|
|
129
|
+
property.name.text === 'namespace' &&
|
|
130
130
|
ts.isStringLiteral(property.initializer)) {
|
|
131
131
|
pushNamespace({ name: property.initializer.text, variable });
|
|
132
132
|
}
|
|
@@ -136,7 +136,7 @@ const getKeys = (path) => {
|
|
|
136
136
|
pushNamespace({ name: argument.text, variable });
|
|
137
137
|
}
|
|
138
138
|
else if (argument === undefined) {
|
|
139
|
-
pushNamespace({ name:
|
|
139
|
+
pushNamespace({ name: '', variable });
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
}
|
|
@@ -225,7 +225,7 @@ const getKeys = (path) => {
|
|
|
225
225
|
}
|
|
226
226
|
if (key) {
|
|
227
227
|
const namespace = getCurrentNamespaceForIdentifier(key.identifier);
|
|
228
|
-
const namespaceName = namespace ? namespace.name :
|
|
228
|
+
const namespaceName = namespace ? namespace.name : '';
|
|
229
229
|
foundKeys.push({
|
|
230
230
|
key: namespaceName ? `${namespaceName}.${key.name}` : key.name,
|
|
231
231
|
meta: { file: path, namespace: namespaceName },
|
|
@@ -249,7 +249,7 @@ const getKeys = (path) => {
|
|
|
249
249
|
const commentKey = COMMENT_CONTAINS_STATIC_KEY_REGEX.exec(comment)?.[2];
|
|
250
250
|
if (commentKey) {
|
|
251
251
|
const namespace = getCurrentNamespaces();
|
|
252
|
-
const namespaceName = namespace ? namespace[0]?.name :
|
|
252
|
+
const namespaceName = namespace ? namespace[0]?.name : '';
|
|
253
253
|
foundKeys.push({
|
|
254
254
|
key: namespaceName
|
|
255
255
|
? `${namespaceName}.${commentKey}`
|