i18next-cli 1.45.0 → 1.46.0
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/dist/cjs/cli.js
CHANGED
|
@@ -28,7 +28,7 @@ const program = new commander.Command();
|
|
|
28
28
|
program
|
|
29
29
|
.name('i18next-cli')
|
|
30
30
|
.description('A unified, high-performance i18next CLI.')
|
|
31
|
-
.version('1.
|
|
31
|
+
.version('1.46.0'); // This string is replaced with the actual version at build time by rollup
|
|
32
32
|
// new: global config override option
|
|
33
33
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
34
34
|
program
|
|
@@ -135,7 +135,13 @@ function extractFromTransComponent(node, config) {
|
|
|
135
135
|
valuesAttr.value.expression.type === 'ObjectExpression') {
|
|
136
136
|
valuesCountProperty = astUtils.getObjectPropValueExpression(valuesAttr.value.expression, 'count');
|
|
137
137
|
}
|
|
138
|
-
|
|
138
|
+
// Mirror react-i18next v16.4.0: infer count from inline {{ count }} children
|
|
139
|
+
// when no explicit `count` prop or `values={{ count }}` is present.
|
|
140
|
+
// The runtime check is `typeof valuesFromChildren.count === 'number'`; at
|
|
141
|
+
// extraction time we can only inspect the AST shape, so we look for any
|
|
142
|
+
// ObjectExpression interpolation that declares a `count` key.
|
|
143
|
+
const hasInlineCount = !countAttr && !valuesCountProperty && childrenHaveInlineCount(node.children);
|
|
144
|
+
const hasCount = !!countAttr || !!valuesCountProperty || hasInlineCount;
|
|
139
145
|
const tOptionsAttr = node.opening.attributes?.find((attr) => attr.type === 'JSXAttribute' &&
|
|
140
146
|
attr.name.type === 'Identifier' &&
|
|
141
147
|
attr.name.value === 'tOptions');
|
|
@@ -385,6 +391,74 @@ function swcChildToReactNode(node) {
|
|
|
385
391
|
function swcChildrenToReactNodes(children) {
|
|
386
392
|
return children.map(swcChildToReactNode).filter(n => n !== null);
|
|
387
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Unwraps TypeScript type-assertion and parenthesis wrappers from a JSX
|
|
396
|
+
* expression so callers can inspect the underlying node type.
|
|
397
|
+
*
|
|
398
|
+
* Handles:
|
|
399
|
+
* `{{ count } as any}` → TsAsExpression wrapping ObjectExpression
|
|
400
|
+
* `{{ count } as TransInterpolation}` → same
|
|
401
|
+
* `({{ count }})` → ParenthesisExpression wrapping ObjectExpression
|
|
402
|
+
*/
|
|
403
|
+
function unwrapJSXExpression(expr) {
|
|
404
|
+
if (expr.type === 'TsAsExpression' || expr.type === 'TsSatisfiesExpression') {
|
|
405
|
+
return unwrapJSXExpression(expr.expression);
|
|
406
|
+
}
|
|
407
|
+
if (expr.type === 'ParenthesisExpression') {
|
|
408
|
+
return unwrapJSXExpression(expr.expression);
|
|
409
|
+
}
|
|
410
|
+
return expr;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Recursively walks JSX children to determine whether any interpolation
|
|
414
|
+
* object contains a `count` property — mirroring the runtime behaviour of
|
|
415
|
+
* react-i18next v16.4.0's `getValuesFromChildren`.
|
|
416
|
+
*
|
|
417
|
+
* This lets the extractor infer `hasCount = true` when a `{{ count }}`
|
|
418
|
+
* (or `{{ count: expr }}`) interpolation is present in children without an
|
|
419
|
+
* explicit `count` prop on the `<Trans>` component.
|
|
420
|
+
*
|
|
421
|
+
* Matches:
|
|
422
|
+
* `{{ count }}` — shorthand Identifier (prop.type === 'Identifier')
|
|
423
|
+
* `{{ count: someExpr }}` — KeyValueProperty with Identifier key
|
|
424
|
+
* `{{ count } as any}` — TsAsExpression-wrapped ObjectExpression
|
|
425
|
+
* Deeply nested in child JSX elements (e.g. `<strong>{{ count }}</strong>`)
|
|
426
|
+
*
|
|
427
|
+
* @param children - The JSX children array to search
|
|
428
|
+
* @returns `true` when a `count` interpolation is found anywhere in the tree
|
|
429
|
+
*/
|
|
430
|
+
function childrenHaveInlineCount(children) {
|
|
431
|
+
for (const child of children) {
|
|
432
|
+
if (child.type === 'JSXExpressionContainer') {
|
|
433
|
+
const inner = unwrapJSXExpression(child.expression);
|
|
434
|
+
if (inner.type === 'ObjectExpression') {
|
|
435
|
+
const hasCount = inner.properties.some(prop => {
|
|
436
|
+
if (prop.type === 'KeyValueProperty') {
|
|
437
|
+
// { count: expr }
|
|
438
|
+
return ((prop.key.type === 'Identifier' || prop.key.type === 'StringLiteral') &&
|
|
439
|
+
prop.key.value === 'count');
|
|
440
|
+
}
|
|
441
|
+
if (prop.type === 'Identifier') {
|
|
442
|
+
// shorthand { count }
|
|
443
|
+
return prop.value === 'count';
|
|
444
|
+
}
|
|
445
|
+
return false;
|
|
446
|
+
});
|
|
447
|
+
if (hasCount)
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else if (child.type === 'JSXElement') {
|
|
452
|
+
if (childrenHaveInlineCount(child.children))
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
else if (child.type === 'JSXFragment') {
|
|
456
|
+
if (childrenHaveInlineCount(child.children))
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
388
462
|
function serializeJSXChildren(children, config) {
|
|
389
463
|
const i18nextOptions = { ...reactI18next.getDefaults() };
|
|
390
464
|
if (config.extract.transKeepBasicHtmlNodesFor) {
|
package/dist/esm/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ const program = new Command();
|
|
|
26
26
|
program
|
|
27
27
|
.name('i18next-cli')
|
|
28
28
|
.description('A unified, high-performance i18next CLI.')
|
|
29
|
-
.version('1.
|
|
29
|
+
.version('1.46.0'); // This string is replaced with the actual version at build time by rollup
|
|
30
30
|
// new: global config override option
|
|
31
31
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
32
32
|
program
|
|
@@ -133,7 +133,13 @@ function extractFromTransComponent(node, config) {
|
|
|
133
133
|
valuesAttr.value.expression.type === 'ObjectExpression') {
|
|
134
134
|
valuesCountProperty = getObjectPropValueExpression(valuesAttr.value.expression, 'count');
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
// Mirror react-i18next v16.4.0: infer count from inline {{ count }} children
|
|
137
|
+
// when no explicit `count` prop or `values={{ count }}` is present.
|
|
138
|
+
// The runtime check is `typeof valuesFromChildren.count === 'number'`; at
|
|
139
|
+
// extraction time we can only inspect the AST shape, so we look for any
|
|
140
|
+
// ObjectExpression interpolation that declares a `count` key.
|
|
141
|
+
const hasInlineCount = !countAttr && !valuesCountProperty && childrenHaveInlineCount(node.children);
|
|
142
|
+
const hasCount = !!countAttr || !!valuesCountProperty || hasInlineCount;
|
|
137
143
|
const tOptionsAttr = node.opening.attributes?.find((attr) => attr.type === 'JSXAttribute' &&
|
|
138
144
|
attr.name.type === 'Identifier' &&
|
|
139
145
|
attr.name.value === 'tOptions');
|
|
@@ -383,6 +389,74 @@ function swcChildToReactNode(node) {
|
|
|
383
389
|
function swcChildrenToReactNodes(children) {
|
|
384
390
|
return children.map(swcChildToReactNode).filter(n => n !== null);
|
|
385
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* Unwraps TypeScript type-assertion and parenthesis wrappers from a JSX
|
|
394
|
+
* expression so callers can inspect the underlying node type.
|
|
395
|
+
*
|
|
396
|
+
* Handles:
|
|
397
|
+
* `{{ count } as any}` → TsAsExpression wrapping ObjectExpression
|
|
398
|
+
* `{{ count } as TransInterpolation}` → same
|
|
399
|
+
* `({{ count }})` → ParenthesisExpression wrapping ObjectExpression
|
|
400
|
+
*/
|
|
401
|
+
function unwrapJSXExpression(expr) {
|
|
402
|
+
if (expr.type === 'TsAsExpression' || expr.type === 'TsSatisfiesExpression') {
|
|
403
|
+
return unwrapJSXExpression(expr.expression);
|
|
404
|
+
}
|
|
405
|
+
if (expr.type === 'ParenthesisExpression') {
|
|
406
|
+
return unwrapJSXExpression(expr.expression);
|
|
407
|
+
}
|
|
408
|
+
return expr;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Recursively walks JSX children to determine whether any interpolation
|
|
412
|
+
* object contains a `count` property — mirroring the runtime behaviour of
|
|
413
|
+
* react-i18next v16.4.0's `getValuesFromChildren`.
|
|
414
|
+
*
|
|
415
|
+
* This lets the extractor infer `hasCount = true` when a `{{ count }}`
|
|
416
|
+
* (or `{{ count: expr }}`) interpolation is present in children without an
|
|
417
|
+
* explicit `count` prop on the `<Trans>` component.
|
|
418
|
+
*
|
|
419
|
+
* Matches:
|
|
420
|
+
* `{{ count }}` — shorthand Identifier (prop.type === 'Identifier')
|
|
421
|
+
* `{{ count: someExpr }}` — KeyValueProperty with Identifier key
|
|
422
|
+
* `{{ count } as any}` — TsAsExpression-wrapped ObjectExpression
|
|
423
|
+
* Deeply nested in child JSX elements (e.g. `<strong>{{ count }}</strong>`)
|
|
424
|
+
*
|
|
425
|
+
* @param children - The JSX children array to search
|
|
426
|
+
* @returns `true` when a `count` interpolation is found anywhere in the tree
|
|
427
|
+
*/
|
|
428
|
+
function childrenHaveInlineCount(children) {
|
|
429
|
+
for (const child of children) {
|
|
430
|
+
if (child.type === 'JSXExpressionContainer') {
|
|
431
|
+
const inner = unwrapJSXExpression(child.expression);
|
|
432
|
+
if (inner.type === 'ObjectExpression') {
|
|
433
|
+
const hasCount = inner.properties.some(prop => {
|
|
434
|
+
if (prop.type === 'KeyValueProperty') {
|
|
435
|
+
// { count: expr }
|
|
436
|
+
return ((prop.key.type === 'Identifier' || prop.key.type === 'StringLiteral') &&
|
|
437
|
+
prop.key.value === 'count');
|
|
438
|
+
}
|
|
439
|
+
if (prop.type === 'Identifier') {
|
|
440
|
+
// shorthand { count }
|
|
441
|
+
return prop.value === 'count';
|
|
442
|
+
}
|
|
443
|
+
return false;
|
|
444
|
+
});
|
|
445
|
+
if (hasCount)
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
else if (child.type === 'JSXElement') {
|
|
450
|
+
if (childrenHaveInlineCount(child.children))
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
else if (child.type === 'JSXFragment') {
|
|
454
|
+
if (childrenHaveInlineCount(child.children))
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
386
460
|
function serializeJSXChildren(children, config) {
|
|
387
461
|
const i18nextOptions = { ...getDefaults() };
|
|
388
462
|
if (config.extract.transKeepBasicHtmlNodesFor) {
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAsC,UAAU,EAAkD,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC7J,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAsEvD,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAE3B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAE/B,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAE/B,kHAAkH;IAClH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA4BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,yBAAyB,CAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,GAAG,sBAAsB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"jsx-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAsC,UAAU,EAAkD,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC7J,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAsEvD,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAE3B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAE/B,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAE/B,kHAAkH;IAClH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA4BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,yBAAyB,CAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,GAAG,sBAAsB,GAAG,IAAI,CAkMxH"}
|