@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
|
@@ -2,204 +2,204 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const findInvalidi18nTranslations_1 = require("./findInvalidi18nTranslations");
|
|
4
4
|
const flattenTranslations_1 = require("./flattenTranslations");
|
|
5
|
-
const sourceFile = require(
|
|
6
|
-
const targetFile = require(
|
|
7
|
-
describe(
|
|
8
|
-
it(
|
|
5
|
+
const sourceFile = require('../../translations/i18NextMessageExamples/en-us.json');
|
|
6
|
+
const targetFile = require('../../translations/i18NextMessageExamples/de-de.json');
|
|
7
|
+
describe('findInvalid18nTranslations:compareTranslationFiles', () => {
|
|
8
|
+
it('should return empty array if files are identical', () => {
|
|
9
9
|
expect((0, findInvalidi18nTranslations_1.compareTranslationFiles)((0, flattenTranslations_1.flattenTranslations)(sourceFile), (0, flattenTranslations_1.flattenTranslations)(sourceFile))).toEqual([]);
|
|
10
10
|
});
|
|
11
|
-
it(
|
|
11
|
+
it('should return the invalid keys in the target file', () => {
|
|
12
12
|
expect((0, findInvalidi18nTranslations_1.compareTranslationFiles)((0, flattenTranslations_1.flattenTranslations)({
|
|
13
13
|
...sourceFile,
|
|
14
|
-
|
|
14
|
+
'ten.eleven.twelve': 'ten eleven twelve',
|
|
15
15
|
}), (0, flattenTranslations_1.flattenTranslations)(targetFile))).toEqual([
|
|
16
16
|
{
|
|
17
|
-
key:
|
|
18
|
-
msg:
|
|
17
|
+
key: 'key_with_broken_de',
|
|
18
|
+
msg: 'Error in interpolation: Expected value but received val',
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
|
-
key:
|
|
22
|
-
msg:
|
|
21
|
+
key: 'intlNumber_broken_de',
|
|
22
|
+
msg: 'Missing element interpolation',
|
|
23
23
|
},
|
|
24
24
|
]);
|
|
25
25
|
});
|
|
26
|
-
it(
|
|
26
|
+
it('should return an empty array if the strings contain paranthesis that have different content', () => {
|
|
27
27
|
expect((0, findInvalidi18nTranslations_1.compareTranslationFiles)((0, flattenTranslations_1.flattenTranslations)({
|
|
28
|
-
keyText:
|
|
29
|
-
}), (0, flattenTranslations_1.flattenTranslations)({ keyText:
|
|
28
|
+
keyText: 'Key(s)',
|
|
29
|
+
}), (0, flattenTranslations_1.flattenTranslations)({ keyText: 'Taste(n)' }))).toEqual([]);
|
|
30
30
|
});
|
|
31
|
-
it(
|
|
31
|
+
it('should return empty array if placeholders are identical but in different positions', () => {
|
|
32
32
|
expect((0, findInvalidi18nTranslations_1.compareTranslationFiles)({
|
|
33
|
-
basic:
|
|
33
|
+
basic: 'added {{this}} and {{that}} should work.',
|
|
34
34
|
}, {
|
|
35
|
-
basic:
|
|
35
|
+
basic: 'It is {{this}} with different position {{that}}',
|
|
36
36
|
})).toEqual([]);
|
|
37
37
|
});
|
|
38
|
-
it(
|
|
38
|
+
it('should return the invalid key if tags are not identical', () => {
|
|
39
39
|
expect((0, findInvalidi18nTranslations_1.compareTranslationFiles)({
|
|
40
|
-
tag:
|
|
40
|
+
tag: 'This is some <b>bold text</b> and some <i>italic</i> text.',
|
|
41
41
|
}, {
|
|
42
|
-
tag:
|
|
42
|
+
tag: 'There is some <b>bold text</b> and some other <span>italic</span> text.',
|
|
43
43
|
})).toEqual([
|
|
44
44
|
{
|
|
45
|
-
key:
|
|
45
|
+
key: 'tag',
|
|
46
46
|
msg: 'Expected tag "</i>" but received "</span>", Expected tag "<i>" but received "<span>"',
|
|
47
47
|
},
|
|
48
48
|
]);
|
|
49
49
|
});
|
|
50
|
-
it(
|
|
50
|
+
it('should return empty array if tags are identical', () => {
|
|
51
51
|
expect((0, findInvalidi18nTranslations_1.compareTranslationFiles)({
|
|
52
|
-
tag:
|
|
52
|
+
tag: 'This is some <b>bold text</b> and some <i>italic</i> text.',
|
|
53
53
|
}, {
|
|
54
|
-
tag:
|
|
54
|
+
tag: 'There is some <b>bold text</b> and some other <i>italic</i> text.',
|
|
55
55
|
})).toEqual([]);
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
|
-
describe(
|
|
59
|
-
it(
|
|
58
|
+
describe('findInvalidTranslations', () => {
|
|
59
|
+
it('should return an empty object if all files have no invalid keys', () => {
|
|
60
60
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)(sourceFile, { de: sourceFile })).toEqual({});
|
|
61
61
|
});
|
|
62
|
-
it(
|
|
63
|
-
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({ ...sourceFile,
|
|
62
|
+
it('should return an object containing the keys for the missing language', () => {
|
|
63
|
+
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({ ...sourceFile, 'ten.eleven.twelve': 'ten eleven twelve' }, { de: targetFile })).toEqual({
|
|
64
64
|
de: [
|
|
65
65
|
{
|
|
66
|
-
key:
|
|
67
|
-
msg:
|
|
66
|
+
key: 'key_with_broken_de',
|
|
67
|
+
msg: 'Error in interpolation: Expected value but received val',
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
|
-
key:
|
|
71
|
-
msg:
|
|
70
|
+
key: 'intlNumber_broken_de',
|
|
71
|
+
msg: 'Missing element interpolation',
|
|
72
72
|
},
|
|
73
73
|
],
|
|
74
74
|
});
|
|
75
75
|
});
|
|
76
|
-
it(
|
|
77
|
-
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({ ...sourceFile,
|
|
76
|
+
it('should return an object containing the keys for every language with missing key', () => {
|
|
77
|
+
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({ ...sourceFile, 'ten.eleven.twelve': 'ten eleven twelve' }, {
|
|
78
78
|
de: targetFile,
|
|
79
79
|
fr: {
|
|
80
|
-
key_with_broken_de:
|
|
80
|
+
key_with_broken_de: 'Some format {{value, formatname}} and some other format {{value, formatname}}',
|
|
81
81
|
},
|
|
82
82
|
})).toEqual({
|
|
83
83
|
de: [
|
|
84
84
|
{
|
|
85
|
-
key:
|
|
86
|
-
msg:
|
|
85
|
+
key: 'key_with_broken_de',
|
|
86
|
+
msg: 'Error in interpolation: Expected value but received val',
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
|
-
key:
|
|
90
|
-
msg:
|
|
89
|
+
key: 'intlNumber_broken_de',
|
|
90
|
+
msg: 'Missing element interpolation',
|
|
91
91
|
},
|
|
92
92
|
],
|
|
93
93
|
fr: [
|
|
94
94
|
{
|
|
95
|
-
key:
|
|
96
|
-
msg:
|
|
95
|
+
key: 'key_with_broken_de',
|
|
96
|
+
msg: 'Unexpected interpolation element',
|
|
97
97
|
},
|
|
98
98
|
],
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
|
-
it(
|
|
101
|
+
it('should find invalid interval', () => {
|
|
102
102
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
103
|
-
key1_interval:
|
|
103
|
+
key1_interval: '(1)[one item];(2-7)[a few items];(7-inf)[a lot of items];',
|
|
104
104
|
}, {
|
|
105
105
|
de: {
|
|
106
|
-
key1_interval:
|
|
106
|
+
key1_interval: '(1-2)[one or two items];(3-7)[a few items];(7-inf)[a lot of items];',
|
|
107
107
|
},
|
|
108
108
|
})).toEqual({
|
|
109
109
|
de: [
|
|
110
110
|
{
|
|
111
|
-
key:
|
|
112
|
-
msg:
|
|
111
|
+
key: 'key1_interval',
|
|
112
|
+
msg: 'Error in plural: Expected 1 but received 1-2, Error in plural: Expected 2-7 but received 3-7',
|
|
113
113
|
},
|
|
114
114
|
],
|
|
115
115
|
});
|
|
116
116
|
});
|
|
117
|
-
it(
|
|
117
|
+
it('should find invalid nested interpolation', () => {
|
|
118
118
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
119
|
-
|
|
119
|
+
'tree.one': 'added {{something}}',
|
|
120
120
|
}, {
|
|
121
121
|
de: {
|
|
122
|
-
|
|
122
|
+
'tree.one': 'added {{somethings}}',
|
|
123
123
|
},
|
|
124
124
|
})).toEqual({
|
|
125
125
|
de: [
|
|
126
126
|
{
|
|
127
|
-
key:
|
|
128
|
-
msg:
|
|
127
|
+
key: 'tree.one',
|
|
128
|
+
msg: 'Error in interpolation: Expected something but received somethings',
|
|
129
129
|
},
|
|
130
130
|
],
|
|
131
131
|
});
|
|
132
132
|
});
|
|
133
|
-
it(
|
|
133
|
+
it('should find invalid relative time formatting', () => {
|
|
134
134
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
135
|
-
intlRelativeTimeWithOptionsExplicit:
|
|
135
|
+
intlRelativeTimeWithOptionsExplicit: 'Lorem {{val, relativetime(range: quarter; style: narrow;)}}',
|
|
136
136
|
}, {
|
|
137
137
|
de: {
|
|
138
|
-
intlRelativeTimeWithOptionsExplicit:
|
|
138
|
+
intlRelativeTimeWithOptionsExplicit: 'Lorem {{val, relativetime(range: quarter; style: long;)}}',
|
|
139
139
|
},
|
|
140
140
|
})).toEqual({
|
|
141
141
|
de: [
|
|
142
142
|
{
|
|
143
|
-
key:
|
|
144
|
-
msg:
|
|
143
|
+
key: 'intlRelativeTimeWithOptionsExplicit',
|
|
144
|
+
msg: 'Error in interpolation: Expected relativetime(range: quarter; style: narrow;) but received relativetime(range: quarter; style: long;)',
|
|
145
145
|
},
|
|
146
146
|
],
|
|
147
147
|
});
|
|
148
148
|
});
|
|
149
|
-
it(
|
|
149
|
+
it('should find invalid key with options', () => {
|
|
150
150
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
151
|
-
keyWithOptions:
|
|
151
|
+
keyWithOptions: 'Some format {{value, formatname(option1Name: option1Value; option2Name: option2Value)}}',
|
|
152
152
|
}, {
|
|
153
153
|
de: {
|
|
154
|
-
keyWithOptions:
|
|
154
|
+
keyWithOptions: 'Some format {{value, formatname(option3Name: option3Value; option4Name: option4Value)}}',
|
|
155
155
|
},
|
|
156
156
|
})).toEqual({
|
|
157
157
|
de: [
|
|
158
158
|
{
|
|
159
|
-
key:
|
|
160
|
-
msg:
|
|
159
|
+
key: 'keyWithOptions',
|
|
160
|
+
msg: 'Error in interpolation: Expected formatname(option1Name: option1Value; option2Name: option2Value) but received formatname(option3Name: option3Value; option4Name: option4Value)',
|
|
161
161
|
},
|
|
162
162
|
],
|
|
163
163
|
});
|
|
164
164
|
});
|
|
165
|
-
it(
|
|
165
|
+
it('should find invalid nesting', () => {
|
|
166
166
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
167
|
-
nesting1:
|
|
167
|
+
nesting1: '1 $t(nesting2)',
|
|
168
168
|
}, {
|
|
169
169
|
de: {
|
|
170
|
-
nesting1:
|
|
170
|
+
nesting1: '1 $t(nesting3)',
|
|
171
171
|
},
|
|
172
172
|
})).toEqual({
|
|
173
173
|
de: [
|
|
174
174
|
{
|
|
175
|
-
key:
|
|
176
|
-
msg:
|
|
175
|
+
key: 'nesting1',
|
|
176
|
+
msg: 'Error in nesting: Expected nesting2 but received nesting3',
|
|
177
177
|
},
|
|
178
178
|
],
|
|
179
179
|
});
|
|
180
180
|
});
|
|
181
|
-
it(
|
|
181
|
+
it('should find invalid tags', () => {
|
|
182
182
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
183
|
-
tag:
|
|
183
|
+
tag: 'This is some <b>bold text</b> and some <i>italic</i> text.',
|
|
184
184
|
}, {
|
|
185
185
|
de: {
|
|
186
|
-
tag:
|
|
186
|
+
tag: 'There is some <b>bold text</b> and some other <span>text inside a span</span>!',
|
|
187
187
|
},
|
|
188
188
|
})).toEqual({
|
|
189
189
|
de: [
|
|
190
190
|
{
|
|
191
|
-
key:
|
|
191
|
+
key: 'tag',
|
|
192
192
|
msg: 'Expected tag "</i>" but received "</span>", Expected tag "<i>" but received "<span>"',
|
|
193
193
|
},
|
|
194
194
|
],
|
|
195
195
|
});
|
|
196
196
|
});
|
|
197
|
-
it(
|
|
197
|
+
it('should recognize special characters', () => {
|
|
198
198
|
expect((0, findInvalidi18nTranslations_1.findInvalid18nTranslations)({
|
|
199
|
-
key:
|
|
199
|
+
key: 'Test < {{a}} and > {{max_a}}',
|
|
200
200
|
}, {
|
|
201
201
|
de: {
|
|
202
|
-
key:
|
|
202
|
+
key: 'Test < {{a}} und > {{max_a}}',
|
|
203
203
|
},
|
|
204
204
|
})).toEqual({});
|
|
205
205
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Translation } from
|
|
1
|
+
import { Translation } from '../types';
|
|
2
2
|
export declare const findMissingKeys: (source: Translation, targets: Record<string, Translation>) => Record<string, string[]>;
|
|
3
3
|
export declare const compareTranslationFiles: (a: Translation, b: Translation) => string[];
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.compareTranslationFiles = exports.findMissingKeys = void 0;
|
|
4
4
|
const findMissingKeys = (source, targets) => {
|
|
5
|
-
|
|
5
|
+
const differences = {};
|
|
6
6
|
for (const [lang, file] of Object.entries(targets)) {
|
|
7
7
|
const result = (0, exports.compareTranslationFiles)(source, file);
|
|
8
8
|
if (result.length > 0) {
|
|
@@ -13,7 +13,7 @@ const findMissingKeys = (source, targets) => {
|
|
|
13
13
|
};
|
|
14
14
|
exports.findMissingKeys = findMissingKeys;
|
|
15
15
|
const compareTranslationFiles = (a, b) => {
|
|
16
|
-
|
|
16
|
+
const diffs = [];
|
|
17
17
|
for (const key in a) {
|
|
18
18
|
const counterKey = b[key];
|
|
19
19
|
if (!counterKey) {
|
|
@@ -2,40 +2,40 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const findMissingKeys_1 = require("./findMissingKeys");
|
|
4
4
|
const sourceFile = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
'one.two.three': 'one two three',
|
|
6
|
+
'four.five.six': 'four five six',
|
|
7
|
+
'seven.eight.nine': 'seven eight nine',
|
|
8
8
|
};
|
|
9
9
|
const secondaryFile = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
'one.two.three': 'one two three',
|
|
11
|
+
'four.five.six': 'four five six',
|
|
12
|
+
'seven.eight.nine': 'seven eight nine',
|
|
13
13
|
};
|
|
14
|
-
describe(
|
|
15
|
-
it(
|
|
14
|
+
describe('findMissingKeys:compareTranslationFiles', () => {
|
|
15
|
+
it('should return empty array if files are identical', () => {
|
|
16
16
|
expect((0, findMissingKeys_1.compareTranslationFiles)(sourceFile, secondaryFile)).toEqual([]);
|
|
17
17
|
});
|
|
18
|
-
it(
|
|
19
|
-
expect((0, findMissingKeys_1.compareTranslationFiles)({ ...sourceFile,
|
|
18
|
+
it('should return the missing keys in the secondary file', () => {
|
|
19
|
+
expect((0, findMissingKeys_1.compareTranslationFiles)({ ...sourceFile, 'ten.eleven.twelve': 'ten eleven twelve' }, secondaryFile)).toEqual(['ten.eleven.twelve']);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
|
-
describe(
|
|
23
|
-
it(
|
|
22
|
+
describe('findMissingKeys', () => {
|
|
23
|
+
it('should return an empty object if all files have no missing keys', () => {
|
|
24
24
|
expect((0, findMissingKeys_1.findMissingKeys)(sourceFile, { de: secondaryFile })).toEqual({});
|
|
25
25
|
});
|
|
26
|
-
it(
|
|
27
|
-
expect((0, findMissingKeys_1.findMissingKeys)({ ...sourceFile,
|
|
26
|
+
it('should return an object containing the keys for the missing language', () => {
|
|
27
|
+
expect((0, findMissingKeys_1.findMissingKeys)({ ...sourceFile, 'ten.eleven.twelve': 'ten eleven twelve' }, { de: secondaryFile })).toEqual({ de: ['ten.eleven.twelve'] });
|
|
28
28
|
});
|
|
29
|
-
it(
|
|
30
|
-
expect((0, findMissingKeys_1.findMissingKeys)({ ...sourceFile,
|
|
29
|
+
it('should return an object containing the keys for every language with missing key', () => {
|
|
30
|
+
expect((0, findMissingKeys_1.findMissingKeys)({ ...sourceFile, 'ten.eleven.twelve': 'ten eleven twelve' }, {
|
|
31
31
|
de: secondaryFile,
|
|
32
32
|
fr: {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
'four.five.six': 'four five six',
|
|
34
|
+
'seven.eight.nine': 'seven eight nine',
|
|
35
35
|
},
|
|
36
36
|
})).toEqual({
|
|
37
|
-
de: [
|
|
38
|
-
fr: [
|
|
37
|
+
de: ['ten.eleven.twelve'],
|
|
38
|
+
fr: ['one.two.three', 'ten.eleven.twelve'],
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
41
|
});
|
|
@@ -12,10 +12,10 @@ exports.flattenTranslations = flattenTranslations;
|
|
|
12
12
|
* Top level search for any objects
|
|
13
13
|
*/
|
|
14
14
|
const hasNestedDefinitions = (translations) => {
|
|
15
|
-
return Object.values(translations).find((translation) => typeof translation ===
|
|
15
|
+
return Object.values(translations).find((translation) => typeof translation === 'object');
|
|
16
16
|
};
|
|
17
17
|
const isTranslationObject = (entry) => {
|
|
18
|
-
return typeof entry ===
|
|
18
|
+
return typeof entry === 'object';
|
|
19
19
|
};
|
|
20
20
|
const flattenEntry = (entry, keys = []) => {
|
|
21
21
|
const result = {};
|
|
@@ -26,7 +26,7 @@ const flattenEntry = (entry, keys = []) => {
|
|
|
26
26
|
for (const [k, v] of entries) {
|
|
27
27
|
Object.assign(result, isTranslationObject(v)
|
|
28
28
|
? (0, exports.flattenEntry)(v, [...keys, String(k)])
|
|
29
|
-
: { [[...keys, String(k)].join(
|
|
29
|
+
: { [[...keys, String(k)].join('.')]: v });
|
|
30
30
|
}
|
|
31
31
|
return result;
|
|
32
32
|
};
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const flattenTranslations_1 = require("./flattenTranslations");
|
|
4
|
-
const flatStructure = require(
|
|
5
|
-
const nestedStructure = require(
|
|
4
|
+
const flatStructure = require('../../translations/en-us.json');
|
|
5
|
+
const nestedStructure = require('../../translations/flattenExamples/en-us.json');
|
|
6
6
|
const expectedFlatStructure = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
'test.drive.one': 'testing one',
|
|
8
|
+
'test.drive.two': 'testing two',
|
|
9
|
+
'other.nested.three': 'testing three',
|
|
10
|
+
'other.nested.deep.more.final': 'nested translation',
|
|
11
11
|
};
|
|
12
|
-
describe(
|
|
13
|
-
it(
|
|
12
|
+
describe('flattenTranslations', () => {
|
|
13
|
+
it('should do nothing if the file structure is flat', () => {
|
|
14
14
|
expect((0, flattenTranslations_1.flattenTranslations)(flatStructure)).toEqual(flatStructure);
|
|
15
15
|
});
|
|
16
|
-
describe(
|
|
17
|
-
it(
|
|
16
|
+
describe('flattenEntry', () => {
|
|
17
|
+
it('should flatten a nested object', () => {
|
|
18
18
|
expect((0, flattenTranslations_1.flattenEntry)({
|
|
19
19
|
a: {
|
|
20
|
-
b: { c:
|
|
20
|
+
b: { c: 'one' },
|
|
21
21
|
},
|
|
22
|
-
})).toEqual({
|
|
22
|
+
})).toEqual({ 'a.b.c': 'one' });
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
|
-
it(
|
|
25
|
+
it('should do nothing if the file structure is flat', () => {
|
|
26
26
|
expect((0, flattenTranslations_1.flattenTranslations)(nestedStructure)).toEqual(expectedFlatStructure);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
export type MessageFormatElement = {
|
|
2
|
-
type:
|
|
2
|
+
type: 'text';
|
|
3
3
|
content: string;
|
|
4
4
|
} | {
|
|
5
|
-
type:
|
|
5
|
+
type: 'interpolation';
|
|
6
6
|
raw: string;
|
|
7
7
|
prefix: string;
|
|
8
8
|
suffix: string;
|
|
9
9
|
content: string;
|
|
10
10
|
variable: string;
|
|
11
11
|
} | {
|
|
12
|
-
type:
|
|
12
|
+
type: 'interpolation_unescaped';
|
|
13
13
|
raw: string;
|
|
14
14
|
prefix: string;
|
|
15
15
|
suffix: string;
|
|
16
16
|
content: string;
|
|
17
17
|
variable: string;
|
|
18
18
|
} | {
|
|
19
|
-
type:
|
|
19
|
+
type: 'nesting';
|
|
20
20
|
raw: string;
|
|
21
21
|
prefix: string;
|
|
22
22
|
suffix: string;
|
|
23
23
|
content: string;
|
|
24
24
|
variable: string;
|
|
25
25
|
} | {
|
|
26
|
-
type:
|
|
26
|
+
type: 'plural';
|
|
27
27
|
raw: string;
|
|
28
28
|
prefix: string;
|
|
29
29
|
suffix: string;
|
|
30
30
|
content: string;
|
|
31
31
|
variable: string;
|
|
32
32
|
} | {
|
|
33
|
-
type:
|
|
33
|
+
type: 'tag';
|
|
34
34
|
raw: string;
|
|
35
35
|
voidElement: boolean;
|
|
36
36
|
};
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
// Based on https://github.com/i18next/i18next-translation-parser/blob/v1.0.0/src/parse.js
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.parse = void 0;
|
|
5
|
-
const REGEXP = new RegExp(
|
|
6
|
-
const DOUBLE_BRACE =
|
|
7
|
-
const $_T_BRACE =
|
|
8
|
-
const $_T_PARENTHESIS =
|
|
9
|
-
const OPEN_PARENTHESIS =
|
|
10
|
-
const OPEN_TAG =
|
|
11
|
-
const CLOSE_TAG =
|
|
5
|
+
const REGEXP = new RegExp('({{[^}]+}}|\\$t{[^}]+}|\\$t\\([^\\)]+\\)|\\([0-9\\-inf]+\\)(?=\\[)|<[^>]+>)', 'g');
|
|
6
|
+
const DOUBLE_BRACE = '{{';
|
|
7
|
+
const $_T_BRACE = '$t{';
|
|
8
|
+
const $_T_PARENTHESIS = '$t(';
|
|
9
|
+
const OPEN_PARENTHESIS = '(';
|
|
10
|
+
const OPEN_TAG = '<';
|
|
11
|
+
const CLOSE_TAG = '</';
|
|
12
12
|
const parse = (input) => {
|
|
13
13
|
let ast = [];
|
|
14
14
|
ast = parseInput([input]);
|
|
@@ -21,15 +21,15 @@ const parseInput = (input) => {
|
|
|
21
21
|
}
|
|
22
22
|
let ast = [];
|
|
23
23
|
input.forEach((element) => {
|
|
24
|
-
const elements = element.split(REGEXP).filter((element) => element !==
|
|
24
|
+
const elements = element.split(REGEXP).filter((element) => element !== '');
|
|
25
25
|
const result = elements.reduce((acc, match) => {
|
|
26
|
-
if (match.indexOf(
|
|
26
|
+
if (match.indexOf('{{-') === 0) {
|
|
27
27
|
const content = match.substring(3, match.length - 2);
|
|
28
28
|
acc.push({
|
|
29
|
-
type:
|
|
29
|
+
type: 'interpolation_unescaped',
|
|
30
30
|
raw: match,
|
|
31
|
-
prefix:
|
|
32
|
-
suffix:
|
|
31
|
+
prefix: '{{-',
|
|
32
|
+
suffix: '}}',
|
|
33
33
|
content,
|
|
34
34
|
variable: content.trim(),
|
|
35
35
|
});
|
|
@@ -37,10 +37,10 @@ const parseInput = (input) => {
|
|
|
37
37
|
else if (match.indexOf(DOUBLE_BRACE) === 0) {
|
|
38
38
|
const content = match.substring(2, match.length - 2);
|
|
39
39
|
acc.push({
|
|
40
|
-
type:
|
|
40
|
+
type: 'interpolation',
|
|
41
41
|
raw: match,
|
|
42
|
-
prefix:
|
|
43
|
-
suffix:
|
|
42
|
+
prefix: '{{',
|
|
43
|
+
suffix: '}}',
|
|
44
44
|
content,
|
|
45
45
|
variable: content.trim(),
|
|
46
46
|
});
|
|
@@ -48,10 +48,10 @@ const parseInput = (input) => {
|
|
|
48
48
|
else if (match.indexOf($_T_BRACE) === 0) {
|
|
49
49
|
const content = match.substring(3, match.length - 1);
|
|
50
50
|
acc.push({
|
|
51
|
-
type:
|
|
51
|
+
type: 'nesting',
|
|
52
52
|
raw: match,
|
|
53
|
-
prefix:
|
|
54
|
-
suffix:
|
|
53
|
+
prefix: '$t{',
|
|
54
|
+
suffix: '}',
|
|
55
55
|
content,
|
|
56
56
|
variable: content.trim(),
|
|
57
57
|
});
|
|
@@ -59,10 +59,10 @@ const parseInput = (input) => {
|
|
|
59
59
|
else if (match.indexOf($_T_PARENTHESIS) === 0) {
|
|
60
60
|
const content = match.substring(3, match.length - 1);
|
|
61
61
|
acc.push({
|
|
62
|
-
type:
|
|
62
|
+
type: 'nesting',
|
|
63
63
|
raw: match,
|
|
64
|
-
prefix:
|
|
65
|
-
suffix:
|
|
64
|
+
prefix: '$t(',
|
|
65
|
+
suffix: ')',
|
|
66
66
|
content,
|
|
67
67
|
variable: content.trim(),
|
|
68
68
|
});
|
|
@@ -71,30 +71,30 @@ const parseInput = (input) => {
|
|
|
71
71
|
/\([0-9\-inf]+\)/.test(match)) {
|
|
72
72
|
const content = match.substring(1, match.length - 1);
|
|
73
73
|
acc.push({
|
|
74
|
-
type:
|
|
74
|
+
type: 'plural',
|
|
75
75
|
raw: match,
|
|
76
|
-
prefix:
|
|
77
|
-
suffix:
|
|
76
|
+
prefix: '(',
|
|
77
|
+
suffix: ')',
|
|
78
78
|
content,
|
|
79
79
|
variable: content.trim(),
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
else if (match.indexOf(CLOSE_TAG) === 0) {
|
|
83
83
|
acc.push({
|
|
84
|
-
type:
|
|
84
|
+
type: 'tag',
|
|
85
85
|
raw: match,
|
|
86
|
-
voidElement: match.substring(match.length - 2) ===
|
|
86
|
+
voidElement: match.substring(match.length - 2) === '/>',
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
else if (match.indexOf(OPEN_TAG) === 0 && /<[^\s]+/.test(match)) {
|
|
90
90
|
acc.push({
|
|
91
|
-
type:
|
|
91
|
+
type: 'tag',
|
|
92
92
|
raw: match,
|
|
93
|
-
voidElement: match.substring(match.length - 2) ===
|
|
93
|
+
voidElement: match.substring(match.length - 2) === '/>',
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
else {
|
|
97
|
-
acc.push({ type:
|
|
97
|
+
acc.push({ type: 'text', content: match });
|
|
98
98
|
}
|
|
99
99
|
return acc;
|
|
100
100
|
}, []);
|