i18next-cli 1.67.1 → 1.67.2
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 +1 -1
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/linter.js +21 -16
- package/dist/esm/cli.js +1 -1
- package/dist/esm/linter.js +21 -16
- package/package.json +1 -1
- package/types/linter.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -317,7 +317,7 @@ npx i18next-cli lint
|
|
|
317
317
|
|
|
318
318
|
- **Hardcoded strings** *(error)* — user-facing text in JSX elements and attributes that isn't wrapped in `t()`/`<Trans>`.
|
|
319
319
|
- **Interpolation parameters** *(error)* — mismatches between `{{placeholders}}` in a translation and the params passed to `t()` (missing or unused). Toggle with `lint.checkInterpolationParams` (default: `true`).
|
|
320
|
-
- **String concatenation** *(warning by default)* — translated strings glued together with `+`, or a sentence split across multiple `<Trans>` components. This breaks in languages that reorder or inflect the pieces; use a single key with placeholders instead. Configure with `lint.checkConcatenation`: `'warn'` / `true` (default) reports it without failing the run, `'error'` makes it fail (exit non-zero, useful for CI), and `'off'` / `false` disables it.
|
|
320
|
+
- **String concatenation** *(warning by default)* — translated strings glued together with `+`, or a sentence split across multiple adjacent translations (`<Trans>` components and/or `{t()}` expressions rendered as siblings). This breaks in languages that reorder or inflect the pieces; use a single key with placeholders instead. Configure with `lint.checkConcatenation`: `'warn'` / `true` (default) reports it without failing the run, `'error'` makes it fail (exit non-zero, useful for CI), and `'off'` / `false` disables it.
|
|
321
321
|
|
|
322
322
|
```jsx
|
|
323
323
|
// ⚠️ Flagged — word order can't be translated
|
package/dist/cjs/cli.js
CHANGED
|
@@ -37,7 +37,7 @@ const program = new commander.Command();
|
|
|
37
37
|
program
|
|
38
38
|
.name('i18next-cli')
|
|
39
39
|
.description('A unified, high-performance i18next CLI.')
|
|
40
|
-
.version('1.67.
|
|
40
|
+
.version('1.67.2'); // This string is replaced with the actual version at build time by rollup
|
|
41
41
|
// new: global config override option
|
|
42
42
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
43
43
|
program
|
package/dist/cjs/linter.js
CHANGED
|
@@ -315,8 +315,10 @@ function lintInterpolationParams(ast, code, config, translationValues) {
|
|
|
315
315
|
* Flags two patterns:
|
|
316
316
|
* JS — a `+` expression where an operand is a t() call:
|
|
317
317
|
* t('greeting') + ', ' + name
|
|
318
|
-
* JSX — a sentence split across ≥2
|
|
319
|
-
*
|
|
318
|
+
* JSX — a sentence split across ≥2 adjacent translation units (a <Trans>
|
|
319
|
+
* component or a `{t(...)}` expression) rendered as direct siblings:
|
|
320
|
+
* <p><Trans>Hello</Trans> <Trans>World</Trans></p>
|
|
321
|
+
* <p><Trans>new</Trans>{t('cat')}</p>
|
|
320
322
|
*
|
|
321
323
|
* The fix in both cases is a single key with placeholders:
|
|
322
324
|
* t('greeting', { name }) / <Trans i18nKey="greeting">Hello {{name}}</Trans>
|
|
@@ -390,30 +392,33 @@ function lintConcatenation(ast, code, config) {
|
|
|
390
392
|
});
|
|
391
393
|
}
|
|
392
394
|
}
|
|
393
|
-
// JSX: a sentence split across ≥2
|
|
395
|
+
// JSX: a sentence split across ≥2 adjacent translation units rendered as
|
|
396
|
+
// direct siblings — a <Trans> component or a `{t(...)}` expression. Covers
|
|
397
|
+
// <Trans>…</Trans><Trans>…</Trans>, <Trans>…</Trans>{t(…)} and {t(…)}{t(…)}.
|
|
394
398
|
if ((node.type === 'JSXElement' || node.type === 'JSXFragment') && Array.isArray(node.children)) {
|
|
395
|
-
let
|
|
396
|
-
let
|
|
397
|
-
let hasLiteralText = false;
|
|
399
|
+
let unitCount = 0;
|
|
400
|
+
let firstUnit = null;
|
|
398
401
|
for (const child of node.children) {
|
|
399
402
|
if (!child || typeof child !== 'object')
|
|
400
403
|
continue;
|
|
404
|
+
let isUnit = false;
|
|
401
405
|
if (child.type === 'JSXElement') {
|
|
402
406
|
const name = getJsxName(child);
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
407
|
+
isUnit = !!name && transComponents.has(name.toLowerCase());
|
|
408
|
+
}
|
|
409
|
+
else if (child.type === 'JSXExpressionContainer') {
|
|
410
|
+
isUnit = isTranslationCall(child.expression, config);
|
|
408
411
|
}
|
|
409
|
-
|
|
410
|
-
|
|
412
|
+
if (isUnit) {
|
|
413
|
+
unitCount++;
|
|
414
|
+
if (!firstUnit)
|
|
415
|
+
firstUnit = child;
|
|
411
416
|
}
|
|
412
417
|
}
|
|
413
|
-
if (
|
|
418
|
+
if (unitCount >= 2 && firstUnit) {
|
|
414
419
|
issues.push({
|
|
415
|
-
text: 'Avoid splitting
|
|
416
|
-
line: lineOf(
|
|
420
|
+
text: 'Avoid splitting text across multiple translations (<Trans> or t()). Use a single translation with placeholders instead.',
|
|
421
|
+
line: lineOf(firstUnit),
|
|
417
422
|
type: 'concatenation',
|
|
418
423
|
severity,
|
|
419
424
|
});
|
package/dist/esm/cli.js
CHANGED
|
@@ -31,7 +31,7 @@ const program = new Command();
|
|
|
31
31
|
program
|
|
32
32
|
.name('i18next-cli')
|
|
33
33
|
.description('A unified, high-performance i18next CLI.')
|
|
34
|
-
.version('1.67.
|
|
34
|
+
.version('1.67.2'); // This string is replaced with the actual version at build time by rollup
|
|
35
35
|
// new: global config override option
|
|
36
36
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
37
37
|
program
|
package/dist/esm/linter.js
CHANGED
|
@@ -313,8 +313,10 @@ function lintInterpolationParams(ast, code, config, translationValues) {
|
|
|
313
313
|
* Flags two patterns:
|
|
314
314
|
* JS — a `+` expression where an operand is a t() call:
|
|
315
315
|
* t('greeting') + ', ' + name
|
|
316
|
-
* JSX — a sentence split across ≥2
|
|
317
|
-
*
|
|
316
|
+
* JSX — a sentence split across ≥2 adjacent translation units (a <Trans>
|
|
317
|
+
* component or a `{t(...)}` expression) rendered as direct siblings:
|
|
318
|
+
* <p><Trans>Hello</Trans> <Trans>World</Trans></p>
|
|
319
|
+
* <p><Trans>new</Trans>{t('cat')}</p>
|
|
318
320
|
*
|
|
319
321
|
* The fix in both cases is a single key with placeholders:
|
|
320
322
|
* t('greeting', { name }) / <Trans i18nKey="greeting">Hello {{name}}</Trans>
|
|
@@ -388,30 +390,33 @@ function lintConcatenation(ast, code, config) {
|
|
|
388
390
|
});
|
|
389
391
|
}
|
|
390
392
|
}
|
|
391
|
-
// JSX: a sentence split across ≥2
|
|
393
|
+
// JSX: a sentence split across ≥2 adjacent translation units rendered as
|
|
394
|
+
// direct siblings — a <Trans> component or a `{t(...)}` expression. Covers
|
|
395
|
+
// <Trans>…</Trans><Trans>…</Trans>, <Trans>…</Trans>{t(…)} and {t(…)}{t(…)}.
|
|
392
396
|
if ((node.type === 'JSXElement' || node.type === 'JSXFragment') && Array.isArray(node.children)) {
|
|
393
|
-
let
|
|
394
|
-
let
|
|
395
|
-
let hasLiteralText = false;
|
|
397
|
+
let unitCount = 0;
|
|
398
|
+
let firstUnit = null;
|
|
396
399
|
for (const child of node.children) {
|
|
397
400
|
if (!child || typeof child !== 'object')
|
|
398
401
|
continue;
|
|
402
|
+
let isUnit = false;
|
|
399
403
|
if (child.type === 'JSXElement') {
|
|
400
404
|
const name = getJsxName(child);
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
405
|
+
isUnit = !!name && transComponents.has(name.toLowerCase());
|
|
406
|
+
}
|
|
407
|
+
else if (child.type === 'JSXExpressionContainer') {
|
|
408
|
+
isUnit = isTranslationCall(child.expression, config);
|
|
406
409
|
}
|
|
407
|
-
|
|
408
|
-
|
|
410
|
+
if (isUnit) {
|
|
411
|
+
unitCount++;
|
|
412
|
+
if (!firstUnit)
|
|
413
|
+
firstUnit = child;
|
|
409
414
|
}
|
|
410
415
|
}
|
|
411
|
-
if (
|
|
416
|
+
if (unitCount >= 2 && firstUnit) {
|
|
412
417
|
issues.push({
|
|
413
|
-
text: 'Avoid splitting
|
|
414
|
-
line: lineOf(
|
|
418
|
+
text: 'Avoid splitting text across multiple translations (<Trans> or t()). Use a single translation with placeholders instead.',
|
|
419
|
+
line: lineOf(firstUnit),
|
|
415
420
|
type: 'concatenation',
|
|
416
421
|
severity,
|
|
417
422
|
});
|
package/package.json
CHANGED
package/types/linter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../src/linter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,SAAS,EAA6B,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../src/linter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,SAAS,EAA6B,MAAM,YAAY,CAAA;AAsbpG,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE;QAAC;YACT,OAAO,EAAE,MAAM,CAAC;SACjB;KAAC,CAAC;IACH,IAAI,EAAE;QAAC;YACL,OAAO,EAAE,OAAO,CAAC;YACjB,OAAO,EAAE,MAAM,CAAC;YAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;SACpC;KAAC,CAAC;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;CACvB,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,MAAM,EAAiD,CAAA;AAC7F,eAAO,MAAM,6BAA6B,EAAE,MAAM,EAAqD,CAAA;AAKvG,qBAAa,MAAO,SAAQ,YAAY,CAAC,cAAc,CAAC;IACtD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAQ;gBAET,MAAM,EAAE,oBAAoB,EAAE,MAAM,GAAE,MAA4B;IAM/E,SAAS,CAAE,KAAK,EAAE,OAAO;IAanB,GAAG;;;;;;;IAuIT,OAAO,CAAC,uBAAuB;YAOjB,qBAAqB;IAWnC,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,0BAA0B;YAUpB,qBAAqB;YAgBrB,uBAAuB;CAgBtC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB;;;;;;GAE5D;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,iBA0CnD"}
|