@lingual/i18n-check 0.7.3 → 0.7.5

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.
@@ -53,19 +53,23 @@ const getKeys = (path) => {
53
53
  const sourceFile = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
54
54
  const foundKeys = [];
55
55
  let namespaces = [];
56
- let variable = "t";
57
- const getCurrentNamespace = () => {
56
+ const getCurrentNamespaces = (range = 1) => {
58
57
  if (namespaces.length > 0) {
59
- return namespaces[namespaces.length - 1];
58
+ return namespaces.slice(namespaces.length - range);
60
59
  }
61
60
  return null;
62
61
  };
63
- const pushNamespace = (name) => {
64
- namespaces.push(name);
62
+ const getCurrentNamespaceForIdentifier = (name) => {
63
+ return [...namespaces].reverse().find((namespace) => {
64
+ return namespace.variable === name;
65
+ });
65
66
  };
66
- const removeNamespace = () => {
67
+ const pushNamespace = (namespace) => {
68
+ namespaces.push(namespace);
69
+ };
70
+ const removeNamespaces = (range = 1) => {
67
71
  if (namespaces.length > 0) {
68
- namespaces.pop();
72
+ namespaces = namespaces.slice(0, namespaces.length - range);
69
73
  }
70
74
  };
71
75
  const visit = (node) => {
@@ -82,14 +86,12 @@ const getKeys = (path) => {
82
86
  // from the default `t`, i.e.: const other = useTranslations("namespace1");
83
87
  if (node.initializer.expression.text === USE_TRANSLATIONS) {
84
88
  const [argument] = node.initializer.arguments;
89
+ const variable = ts.isIdentifier(node.name) ? node.name.text : "t";
85
90
  if (argument && ts.isStringLiteral(argument)) {
86
- pushNamespace(argument.text);
91
+ pushNamespace({ name: argument.text, variable });
87
92
  }
88
93
  else if (argument === undefined) {
89
- pushNamespace("");
90
- }
91
- if (ts.isIdentifier(node.name)) {
92
- variable = node.name.text;
94
+ pushNamespace({ name: "", variable });
93
95
  }
94
96
  }
95
97
  }
@@ -109,6 +111,7 @@ const getKeys = (path) => {
109
111
  ts.isIdentifier(node.initializer.expression.expression)) {
110
112
  if (node.initializer.expression.expression.text === GET_TRANSLATIONS) {
111
113
  const [argument] = node.initializer.expression.arguments;
114
+ const variable = ts.isIdentifier(node.name) ? node.name.text : "t";
112
115
  if (argument && ts.isObjectLiteralExpression(argument)) {
113
116
  argument.properties.forEach((property) => {
114
117
  if (property &&
@@ -117,18 +120,15 @@ const getKeys = (path) => {
117
120
  ts.isIdentifier(property.name) &&
118
121
  property.name.text === "namespace" &&
119
122
  ts.isStringLiteral(property.initializer)) {
120
- pushNamespace(property.initializer.text);
123
+ pushNamespace({ name: property.initializer.text, variable });
121
124
  }
122
125
  });
123
126
  }
124
127
  else if (argument && ts.isStringLiteral(argument)) {
125
- pushNamespace(argument.text);
128
+ pushNamespace({ name: argument.text, variable });
126
129
  }
127
130
  else if (argument === undefined) {
128
- pushNamespace("");
129
- }
130
- if (ts.isIdentifier(node.name)) {
131
- variable = node.name.text;
131
+ pushNamespace({ name: "", variable });
132
132
  }
133
133
  }
134
134
  }
@@ -162,49 +162,52 @@ const getKeys = (path) => {
162
162
  if (argument && ts.isStringLiteral(argument)) {
163
163
  inlineNamespace = argument.text;
164
164
  }
165
- }
166
- const [callArgument] = node.expression.arguments;
167
- if (callArgument && ts.isStringLiteral(callArgument)) {
168
- const key = callArgument.text;
169
- if (key) {
170
- foundKeys.push({
171
- key: inlineNamespace ? `${inlineNamespace}.${key}` : key,
172
- meta: { file: path },
173
- });
165
+ const [callArgument] = node.expression.arguments;
166
+ if (callArgument && ts.isStringLiteral(callArgument)) {
167
+ const key = callArgument.text;
168
+ if (key) {
169
+ foundKeys.push({
170
+ key: inlineNamespace ? `${inlineNamespace}.${key}` : key,
171
+ meta: { file: path },
172
+ });
173
+ }
174
174
  }
175
175
  }
176
176
  }
177
177
  }
178
178
  }
179
179
  // Search for `t()` calls
180
- if (getCurrentNamespace() !== null &&
180
+ if (getCurrentNamespaces() !== null &&
181
181
  ts.isCallExpression(node) &&
182
182
  ts.isIdentifier(node.expression)) {
183
183
  const expressionName = node.expression.text;
184
- if (expressionName === variable) {
184
+ const namespace = getCurrentNamespaceForIdentifier(expressionName);
185
+ if (namespace) {
185
186
  const [argument] = node.arguments;
186
187
  if (argument && ts.isStringLiteral(argument)) {
187
- key = argument.text;
188
+ key = { name: argument.text, identifier: expressionName };
188
189
  }
189
190
  }
190
191
  }
191
192
  // Search for `t.*()` calls, i.e. t.html() or t.rich()
192
- if (getCurrentNamespace() !== null &&
193
+ if (getCurrentNamespaces() !== null &&
193
194
  ts.isCallExpression(node) &&
194
195
  ts.isPropertyAccessExpression(node.expression) &&
195
196
  ts.isIdentifier(node.expression.expression)) {
196
197
  const expressionName = node.expression.expression.text;
197
- if (expressionName === variable) {
198
+ const namespace = getCurrentNamespaceForIdentifier(expressionName);
199
+ if (namespace) {
198
200
  const [argument] = node.arguments;
199
201
  if (argument && ts.isStringLiteral(argument)) {
200
- key = argument.text;
202
+ key = { name: argument.text, identifier: expressionName };
201
203
  }
202
204
  }
203
205
  }
204
206
  if (key) {
205
- const namespace = getCurrentNamespace();
207
+ const namespace = getCurrentNamespaceForIdentifier(key.identifier);
208
+ const namespaceName = namespace ? namespace.name : "";
206
209
  foundKeys.push({
207
- key: namespace ? `${namespace}.${key}` : key,
210
+ key: namespaceName ? `${namespaceName}.${key.name}` : key.name,
208
211
  meta: { file: path },
209
212
  });
210
213
  }
@@ -225,9 +228,12 @@ const getKeys = (path) => {
225
228
  // capture the string comment
226
229
  const commentKey = COMMENT_CONTAINS_STATIC_KEY_REGEX.exec(comment)?.[2];
227
230
  if (commentKey) {
228
- const namespace = getCurrentNamespace();
231
+ const namespace = getCurrentNamespaces();
232
+ const namespaceName = namespace ? namespace[0]?.name : "";
229
233
  foundKeys.push({
230
- key: namespace ? `${namespace}.${commentKey}` : commentKey,
234
+ key: namespaceName
235
+ ? `${namespaceName}.${commentKey}`
236
+ : commentKey,
231
237
  meta: { file: path },
232
238
  });
233
239
  }
@@ -236,7 +242,7 @@ const getKeys = (path) => {
236
242
  }
237
243
  ts.forEachChild(node, visit);
238
244
  if (ts.isFunctionLike(node) && namespaces.length > current) {
239
- removeNamespace();
245
+ removeNamespaces(namespaces.length - current);
240
246
  }
241
247
  };
242
248
  ts.forEachChild(sourceFile, visit);
@@ -11,8 +11,9 @@ const counterFile = node_path_1.default.join(srcPath, "Counter.tsx");
11
11
  const clientCounterFile = node_path_1.default.join(srcPath, "ClientCounter.tsx");
12
12
  const nestedExampleFile = node_path_1.default.join(srcPath, "NestedExample.tsx");
13
13
  const asyncExampleFile = node_path_1.default.join(srcPath, "AsyncExample.tsx");
14
- const dynamicKeysExamplFile = node_path_1.default.join(srcPath, "DynamicKeysExample.tsx");
14
+ const dynamicKeysExampleFile = node_path_1.default.join(srcPath, "DynamicKeysExample.tsx");
15
15
  const strictTypesExample = node_path_1.default.join(srcPath, "StrictTypesExample.tsx");
16
+ const advancedExample = node_path_1.default.join(srcPath, "AdvancedExample.tsx");
16
17
  describe("nextIntlSrcParser", () => {
17
18
  it("should find all the translation keys", () => {
18
19
  const keys = (0, nextIntlSrcParser_1.extract)([basicFile, counterFile, clientCounterFile]);
@@ -216,7 +217,7 @@ describe("nextIntlSrcParser", () => {
216
217
  ]);
217
218
  });
218
219
  it("should find all dynamic keys defined as comments", () => {
219
- const keys = (0, nextIntlSrcParser_1.extract)([dynamicKeysExamplFile]);
220
+ const keys = (0, nextIntlSrcParser_1.extract)([dynamicKeysExampleFile]);
220
221
  expect(keys).toEqual([
221
222
  {
222
223
  key: "dynamic.three.value",
@@ -477,4 +478,63 @@ describe("nextIntlSrcParser", () => {
477
478
  },
478
479
  ]);
479
480
  });
481
+ it("should find all the keys for multiple useTranslations aliases", () => {
482
+ const keys = (0, nextIntlSrcParser_1.extract)([advancedExample]);
483
+ expect(keys).toEqual([
484
+ {
485
+ key: "aliasNestedOne.one",
486
+ meta: {
487
+ file: advancedExample,
488
+ },
489
+ },
490
+ {
491
+ key: "aliasNestedTwo.two",
492
+ meta: {
493
+ file: advancedExample,
494
+ },
495
+ },
496
+ {
497
+ key: "aliasNestedThree.threeThree",
498
+ meta: {
499
+ file: advancedExample,
500
+ },
501
+ },
502
+ {
503
+ key: "aliasNestedTwo.threeTwo",
504
+ meta: {
505
+ file: advancedExample,
506
+ },
507
+ },
508
+ {
509
+ key: "aliasNestedOne.threeOne",
510
+ meta: {
511
+ file: advancedExample,
512
+ },
513
+ },
514
+ {
515
+ key: "aliasNestedThree.three",
516
+ meta: {
517
+ file: advancedExample,
518
+ },
519
+ },
520
+ {
521
+ key: "aliasNestedFour.four",
522
+ meta: {
523
+ file: advancedExample,
524
+ },
525
+ },
526
+ {
527
+ key: "aliasTwo.keyTwo",
528
+ meta: {
529
+ file: advancedExample,
530
+ },
531
+ },
532
+ {
533
+ key: "aliasOne.keyOne",
534
+ meta: {
535
+ file: advancedExample,
536
+ },
537
+ },
538
+ ]);
539
+ });
480
540
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingual/i18n-check",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "i18n translation messages check",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",