@lingual/i18n-check 0.7.2 → 0.7.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.
@@ -344,11 +344,21 @@ Found unused keys!
344
344
  └───────────────────────────────────────────────────────────────────┴──────────────────┘
345
345
 
346
346
  Found undefined keys!
347
- ┌─────────────────────────────────────────────────────┬──────────────────┐
348
- │ file │ key
349
- ├─────────────────────────────────────────────────────┼──────────────────┤
350
- │ translations/codeExamples/next-intl/src/Basic.tsx │ message.select
351
- └─────────────────────────────────────────────────────┴──────────────────┘
347
+ ┌──────────────────────────────────────────────────────────────────┬───────────────────┐
348
+ │ file │ key
349
+ ├──────────────────────────────────────────────────────────────────┼───────────────────┤
350
+ │ translations/codeExamples/next-intl/src/Basic.tsx │ message.select
351
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ unknown.unknown │
352
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ About.unknown │
353
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ unknown │
354
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ Test.title │
355
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ title │
356
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ unknown.unknown │
357
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ About.unknown │
358
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ unknown │
359
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ Test.title │
360
+ │ translations/codeExamples/next-intl/src/StrictTypesExample.tsx │ title │
361
+ └──────────────────────────────────────────────────────────────────┴───────────────────┘
352
362
 
353
363
  `);
354
364
  done();
@@ -134,6 +134,48 @@ const getKeys = (path) => {
134
134
  }
135
135
  }
136
136
  }
137
+ // Search for direct inline calls and extract namespace and key
138
+ //
139
+ // useTranslations("ns1")("one")
140
+ // useTranslations("ns1").rich("one");
141
+ // useTranslations("ns1").raw("one");
142
+ if (ts.isExpressionStatement(node)) {
143
+ let inlineNamespace = null;
144
+ if (node.expression && ts.isCallExpression(node.expression)) {
145
+ // Search: useTranslations("ns1")("one")
146
+ if (ts.isCallExpression(node.expression.expression) &&
147
+ ts.isIdentifier(node.expression.expression.expression)) {
148
+ if (node.expression.expression.expression.text === USE_TRANSLATIONS) {
149
+ const [argument] = node.expression.expression.arguments;
150
+ if (argument && ts.isStringLiteral(argument)) {
151
+ inlineNamespace = argument.text;
152
+ }
153
+ }
154
+ }
155
+ // Search: useTranslations("ns1").*("one")
156
+ if (ts.isPropertyAccessExpression(node.expression.expression) &&
157
+ ts.isCallExpression(node.expression.expression.expression) &&
158
+ ts.isIdentifier(node.expression.expression.expression.expression)) {
159
+ if (node.expression.expression.expression.expression.text ===
160
+ USE_TRANSLATIONS) {
161
+ const [argument] = node.expression.expression.expression.arguments;
162
+ if (argument && ts.isStringLiteral(argument)) {
163
+ inlineNamespace = argument.text;
164
+ }
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
+ }
175
+ }
176
+ }
177
+ }
178
+ }
137
179
  // Search for `t()` calls
138
180
  if (getCurrentNamespace() !== null &&
139
181
  ts.isCallExpression(node) &&
@@ -12,6 +12,7 @@ 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
14
  const dynamicKeysExamplFile = node_path_1.default.join(srcPath, "DynamicKeysExample.tsx");
15
+ const strictTypesExample = node_path_1.default.join(srcPath, "StrictTypesExample.tsx");
15
16
  describe("nextIntlSrcParser", () => {
16
17
  it("should find all the translation keys", () => {
17
18
  const keys = (0, nextIntlSrcParser_1.extract)([basicFile, counterFile, clientCounterFile]);
@@ -303,4 +304,177 @@ describe("nextIntlSrcParser", () => {
303
304
  },
304
305
  ]);
305
306
  });
307
+ it("should find all strict typed keys", () => {
308
+ const keys = (0, nextIntlSrcParser_1.extract)([strictTypesExample]);
309
+ expect(keys).toEqual([
310
+ {
311
+ key: "unknown.unknown",
312
+ meta: {
313
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
314
+ },
315
+ },
316
+ {
317
+ key: "About.unknown",
318
+ meta: {
319
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
320
+ },
321
+ },
322
+ {
323
+ key: "unknown",
324
+ meta: {
325
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
326
+ },
327
+ },
328
+ {
329
+ key: "Test.title",
330
+ meta: {
331
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
332
+ },
333
+ },
334
+ {
335
+ key: "title",
336
+ meta: {
337
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
338
+ },
339
+ },
340
+ {
341
+ key: "PageLayout.pageTitle",
342
+ meta: {
343
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
344
+ },
345
+ },
346
+ {
347
+ key: "NotFound.title",
348
+ meta: {
349
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
350
+ },
351
+ },
352
+ {
353
+ key: "Navigation.about",
354
+ meta: {
355
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
356
+ },
357
+ },
358
+ {
359
+ key: "About.title",
360
+ meta: {
361
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
362
+ },
363
+ },
364
+ {
365
+ key: "Navigation.about",
366
+ meta: {
367
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
368
+ },
369
+ },
370
+ {
371
+ key: "About.lastUpdated",
372
+ meta: {
373
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
374
+ },
375
+ },
376
+ {
377
+ key: "About.title",
378
+ meta: {
379
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
380
+ },
381
+ },
382
+ {
383
+ key: "StrictTypes.nested.another.level",
384
+ meta: {
385
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
386
+ },
387
+ },
388
+ {
389
+ key: "StrictTypes.nested.hello",
390
+ meta: {
391
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
392
+ },
393
+ },
394
+ {
395
+ key: "unknown.unknown",
396
+ meta: {
397
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
398
+ },
399
+ },
400
+ {
401
+ key: "About.unknown",
402
+ meta: {
403
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
404
+ },
405
+ },
406
+ {
407
+ key: "unknown",
408
+ meta: {
409
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
410
+ },
411
+ },
412
+ {
413
+ key: "Test.title",
414
+ meta: {
415
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
416
+ },
417
+ },
418
+ {
419
+ key: "title",
420
+ meta: {
421
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
422
+ },
423
+ },
424
+ {
425
+ key: "PageLayout.pageTitle",
426
+ meta: {
427
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
428
+ },
429
+ },
430
+ {
431
+ key: "NotFound.title",
432
+ meta: {
433
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
434
+ },
435
+ },
436
+ {
437
+ key: "Navigation.about",
438
+ meta: {
439
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
440
+ },
441
+ },
442
+ {
443
+ key: "About.title",
444
+ meta: {
445
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
446
+ },
447
+ },
448
+ {
449
+ key: "Navigation.about",
450
+ meta: {
451
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
452
+ },
453
+ },
454
+ {
455
+ key: "About.lastUpdated",
456
+ meta: {
457
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
458
+ },
459
+ },
460
+ {
461
+ key: "About.title",
462
+ meta: {
463
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
464
+ },
465
+ },
466
+ {
467
+ key: "StrictTypes.nested.another.level",
468
+ meta: {
469
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
470
+ },
471
+ },
472
+ {
473
+ key: "StrictTypes.nested.hello",
474
+ meta: {
475
+ file: "translations/codeExamples/next-intl/src/StrictTypesExample.tsx",
476
+ },
477
+ },
478
+ ]);
479
+ });
306
480
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingual/i18n-check",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "description": "i18n translation messages check",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@formatjs/cli-lib": "^6.6.6",
22
- "@formatjs/icu-messageformat-parser": "^2.11.0",
22
+ "@formatjs/icu-messageformat-parser": "^2.11.2",
23
23
  "chalk": "^4.1.2",
24
24
  "commander": "^12.1.0",
25
25
  "glob": "^11.0.1",
@@ -30,11 +30,11 @@
30
30
  "devDependencies": {
31
31
  "@types/jest": "^29.5.14",
32
32
  "@types/js-yaml": "^4.0.9",
33
- "@types/node": "^22.10.10",
33
+ "@types/node": "^22.14.1",
34
34
  "@types/vinyl": "^2.0.12",
35
35
  "braces": "^3.0.3",
36
36
  "jest": "^29.7.0",
37
- "ts-jest": "^29.2.6"
37
+ "ts-jest": "^29.3.2"
38
38
  },
39
39
  "repository": {
40
40
  "type": "git",