i18next-cli 1.58.2 → 1.58.3
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 +2 -2
- package/dist/cjs/extractor/parsers/jsx-parser.js +50 -11
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/status.js +1 -1
- package/dist/esm/cli.js +2 -2
- package/dist/esm/extractor/parsers/jsx-parser.js +49 -11
- package/dist/esm/index.js +1 -1
- package/dist/esm/status.js +1 -1
- package/package.json +6 -5
- package/types/extractor/parsers/jsx-parser.d.ts.map +1 -1
package/dist/cjs/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ var node_util = require('node:util');
|
|
|
9
9
|
var config = require('./config.js');
|
|
10
10
|
var heuristicConfig = require('./heuristic-config.js');
|
|
11
11
|
var extractor = require('./extractor/core/extractor.js');
|
|
12
|
-
require('
|
|
12
|
+
require('node:module');
|
|
13
13
|
require('node:path');
|
|
14
14
|
var nestedObject = require('./utils/nested-object.js');
|
|
15
15
|
require('node:fs/promises');
|
|
@@ -32,7 +32,7 @@ const program = new commander.Command();
|
|
|
32
32
|
program
|
|
33
33
|
.name('i18next-cli')
|
|
34
34
|
.description('A unified, high-performance i18next CLI.')
|
|
35
|
-
.version('1.58.
|
|
35
|
+
.version('1.58.3'); // This string is replaced with the actual version at build time by rollup
|
|
36
36
|
// new: global config override option
|
|
37
37
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
38
38
|
program
|
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var astUtils = require('./ast-utils.js');
|
|
4
|
-
var
|
|
4
|
+
var node_module = require('node:module');
|
|
5
5
|
|
|
6
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
7
|
+
let cachedReactI18next;
|
|
8
|
+
function loadReactI18next() {
|
|
9
|
+
if (cachedReactI18next !== undefined)
|
|
10
|
+
return cachedReactI18next;
|
|
11
|
+
try {
|
|
12
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('extractor/parsers/jsx-parser.js', document.baseURI).href)));
|
|
13
|
+
cachedReactI18next = require$1('react-i18next');
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
cachedReactI18next = null;
|
|
17
|
+
}
|
|
18
|
+
return cachedReactI18next;
|
|
19
|
+
}
|
|
20
|
+
let warnedReactI18nextUnavailable = false;
|
|
21
|
+
function warnReactI18nextUnavailable() {
|
|
22
|
+
if (warnedReactI18nextUnavailable)
|
|
23
|
+
return;
|
|
24
|
+
warnedReactI18nextUnavailable = true;
|
|
25
|
+
console.warn("i18next-cli: could not load 'react-i18next' to serialize <Trans> children — " +
|
|
26
|
+
'skipping their default-value extraction. This usually means the installed ' +
|
|
27
|
+
"'react-i18next' and 'i18next' versions are incompatible. Other functionality is unaffected.");
|
|
28
|
+
}
|
|
6
29
|
/**
|
|
7
30
|
* Detects which `$$typeof` symbol react-i18next's `nodesToString` expects
|
|
8
31
|
* from React elements. This matters because npm hoisting can cause
|
|
@@ -11,11 +34,14 @@ var reactI18next = require('react-i18next');
|
|
|
11
34
|
*
|
|
12
35
|
* React 18 uses `Symbol.for('react.element')`, while React 19 uses
|
|
13
36
|
* `Symbol.for('react.transitional.element')` for its element `$$typeof`.
|
|
14
|
-
* By probing `nodesToString`
|
|
15
|
-
*
|
|
16
|
-
*
|
|
37
|
+
* By probing `nodesToString` we ensure the fake elements we build match its
|
|
38
|
+
* `isValidElement` check, regardless of which React it resolved to. Resolved
|
|
39
|
+
* lazily (and cached) the first time we serialize a `<Trans>`.
|
|
17
40
|
*/
|
|
18
|
-
|
|
41
|
+
let cachedReactElementType;
|
|
42
|
+
function resolveReactElementType(rt) {
|
|
43
|
+
if (cachedReactElementType !== undefined)
|
|
44
|
+
return cachedReactElementType;
|
|
19
45
|
const candidates = [
|
|
20
46
|
Symbol.for('react.element'), // React ≤ 18
|
|
21
47
|
Symbol.for('react.transitional.element') // React 19
|
|
@@ -31,16 +57,19 @@ const REACT_ELEMENT_TYPE = (() => {
|
|
|
31
57
|
key: null,
|
|
32
58
|
ref: null
|
|
33
59
|
};
|
|
34
|
-
const result =
|
|
35
|
-
if (result === '<0>x</0>')
|
|
60
|
+
const result = rt.nodesToString([testEl], { ...rt.getDefaults() });
|
|
61
|
+
if (result === '<0>x</0>') {
|
|
62
|
+
cachedReactElementType = sym;
|
|
36
63
|
return sym;
|
|
64
|
+
}
|
|
37
65
|
}
|
|
38
66
|
}
|
|
39
67
|
finally {
|
|
40
68
|
console.warn = savedWarn;
|
|
41
69
|
}
|
|
70
|
+
cachedReactElementType = candidates[0];
|
|
42
71
|
return candidates[0];
|
|
43
|
-
}
|
|
72
|
+
}
|
|
44
73
|
/** `React.Fragment` equivalent – same symbol across all React versions. */
|
|
45
74
|
const REACT_FRAGMENT = Symbol.for('react.fragment');
|
|
46
75
|
/**
|
|
@@ -57,7 +86,9 @@ function createElement(type, props, ...children) {
|
|
|
57
86
|
finalProps.children = children;
|
|
58
87
|
}
|
|
59
88
|
return {
|
|
60
|
-
|
|
89
|
+
// serializeJSXChildren() resolves and caches this before any element is
|
|
90
|
+
// built; the fallback only applies if createElement is ever reached first.
|
|
91
|
+
$$typeof: cachedReactElementType ?? Symbol.for('react.transitional.element'),
|
|
61
92
|
type,
|
|
62
93
|
props: finalProps,
|
|
63
94
|
key: null,
|
|
@@ -460,11 +491,19 @@ function childrenHaveInlineCount(children) {
|
|
|
460
491
|
return false;
|
|
461
492
|
}
|
|
462
493
|
function serializeJSXChildren(children, config) {
|
|
463
|
-
const
|
|
494
|
+
const rt = loadReactI18next();
|
|
495
|
+
if (!rt) {
|
|
496
|
+
warnReactI18nextUnavailable();
|
|
497
|
+
return '';
|
|
498
|
+
}
|
|
499
|
+
// Resolve the element `$$typeof` before swcChildrenToReactNodes() builds any
|
|
500
|
+
// elements via createElement().
|
|
501
|
+
resolveReactElementType(rt);
|
|
502
|
+
const i18nextOptions = { ...rt.getDefaults() };
|
|
464
503
|
if (config.extract.transKeepBasicHtmlNodesFor) {
|
|
465
504
|
i18nextOptions.transKeepBasicHtmlNodesFor = config.extract.transKeepBasicHtmlNodesFor;
|
|
466
505
|
}
|
|
467
|
-
return
|
|
506
|
+
return rt.nodesToString(swcChildrenToReactNodes(children), i18nextOptions);
|
|
468
507
|
}
|
|
469
508
|
|
|
470
509
|
exports.extractFromTransComponent = extractFromTransComponent;
|
package/dist/cjs/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var config = require('./config.js');
|
|
|
4
4
|
var extractor = require('./extractor/core/extractor.js');
|
|
5
5
|
var keyFinder = require('./extractor/core/key-finder.js');
|
|
6
6
|
var translationManager = require('./extractor/core/translation-manager.js');
|
|
7
|
-
require('
|
|
7
|
+
require('node:module');
|
|
8
8
|
var linter = require('./linter.js');
|
|
9
9
|
var syncer = require('./syncer.js');
|
|
10
10
|
var status = require('./status.js');
|
package/dist/cjs/status.js
CHANGED
|
@@ -13,7 +13,7 @@ var pluralRules = require('./utils/plural-rules.js');
|
|
|
13
13
|
var nesting = require('./utils/nesting.js');
|
|
14
14
|
var contextVariants = require('./utils/context-variants.js');
|
|
15
15
|
var funnelMsgTracker = require('./utils/funnel-msg-tracker.js');
|
|
16
|
-
require('
|
|
16
|
+
require('node:module');
|
|
17
17
|
|
|
18
18
|
function classifyValue(value) {
|
|
19
19
|
if (value === undefined || value === null)
|
package/dist/esm/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { styleText } from 'node:util';
|
|
|
7
7
|
import { ensureConfig, loadConfig } from './config.js';
|
|
8
8
|
import { detectConfig } from './heuristic-config.js';
|
|
9
9
|
import { runExtractor } from './extractor/core/extractor.js';
|
|
10
|
-
import '
|
|
10
|
+
import 'node:module';
|
|
11
11
|
import 'node:path';
|
|
12
12
|
import { getNestedKeys, getNestedValue } from './utils/nested-object.js';
|
|
13
13
|
import 'node:fs/promises';
|
|
@@ -30,7 +30,7 @@ const program = new Command();
|
|
|
30
30
|
program
|
|
31
31
|
.name('i18next-cli')
|
|
32
32
|
.description('A unified, high-performance i18next CLI.')
|
|
33
|
-
.version('1.58.
|
|
33
|
+
.version('1.58.3'); // This string is replaced with the actual version at build time by rollup
|
|
34
34
|
// new: global config override option
|
|
35
35
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
36
36
|
program
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import { getObjectPropValueExpression, getObjectPropValue, isSimpleTemplateLiteral } from './ast-utils.js';
|
|
2
|
-
import {
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
3
|
|
|
4
|
+
let cachedReactI18next;
|
|
5
|
+
function loadReactI18next() {
|
|
6
|
+
if (cachedReactI18next !== undefined)
|
|
7
|
+
return cachedReactI18next;
|
|
8
|
+
try {
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
cachedReactI18next = require('react-i18next');
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
cachedReactI18next = null;
|
|
14
|
+
}
|
|
15
|
+
return cachedReactI18next;
|
|
16
|
+
}
|
|
17
|
+
let warnedReactI18nextUnavailable = false;
|
|
18
|
+
function warnReactI18nextUnavailable() {
|
|
19
|
+
if (warnedReactI18nextUnavailable)
|
|
20
|
+
return;
|
|
21
|
+
warnedReactI18nextUnavailable = true;
|
|
22
|
+
console.warn("i18next-cli: could not load 'react-i18next' to serialize <Trans> children — " +
|
|
23
|
+
'skipping their default-value extraction. This usually means the installed ' +
|
|
24
|
+
"'react-i18next' and 'i18next' versions are incompatible. Other functionality is unaffected.");
|
|
25
|
+
}
|
|
4
26
|
/**
|
|
5
27
|
* Detects which `$$typeof` symbol react-i18next's `nodesToString` expects
|
|
6
28
|
* from React elements. This matters because npm hoisting can cause
|
|
@@ -9,11 +31,14 @@ import { nodesToString, getDefaults } from 'react-i18next';
|
|
|
9
31
|
*
|
|
10
32
|
* React 18 uses `Symbol.for('react.element')`, while React 19 uses
|
|
11
33
|
* `Symbol.for('react.transitional.element')` for its element `$$typeof`.
|
|
12
|
-
* By probing `nodesToString`
|
|
13
|
-
*
|
|
14
|
-
*
|
|
34
|
+
* By probing `nodesToString` we ensure the fake elements we build match its
|
|
35
|
+
* `isValidElement` check, regardless of which React it resolved to. Resolved
|
|
36
|
+
* lazily (and cached) the first time we serialize a `<Trans>`.
|
|
15
37
|
*/
|
|
16
|
-
|
|
38
|
+
let cachedReactElementType;
|
|
39
|
+
function resolveReactElementType(rt) {
|
|
40
|
+
if (cachedReactElementType !== undefined)
|
|
41
|
+
return cachedReactElementType;
|
|
17
42
|
const candidates = [
|
|
18
43
|
Symbol.for('react.element'), // React ≤ 18
|
|
19
44
|
Symbol.for('react.transitional.element') // React 19
|
|
@@ -29,16 +54,19 @@ const REACT_ELEMENT_TYPE = (() => {
|
|
|
29
54
|
key: null,
|
|
30
55
|
ref: null
|
|
31
56
|
};
|
|
32
|
-
const result = nodesToString([testEl], { ...getDefaults() });
|
|
33
|
-
if (result === '<0>x</0>')
|
|
57
|
+
const result = rt.nodesToString([testEl], { ...rt.getDefaults() });
|
|
58
|
+
if (result === '<0>x</0>') {
|
|
59
|
+
cachedReactElementType = sym;
|
|
34
60
|
return sym;
|
|
61
|
+
}
|
|
35
62
|
}
|
|
36
63
|
}
|
|
37
64
|
finally {
|
|
38
65
|
console.warn = savedWarn;
|
|
39
66
|
}
|
|
67
|
+
cachedReactElementType = candidates[0];
|
|
40
68
|
return candidates[0];
|
|
41
|
-
}
|
|
69
|
+
}
|
|
42
70
|
/** `React.Fragment` equivalent – same symbol across all React versions. */
|
|
43
71
|
const REACT_FRAGMENT = Symbol.for('react.fragment');
|
|
44
72
|
/**
|
|
@@ -55,7 +83,9 @@ function createElement(type, props, ...children) {
|
|
|
55
83
|
finalProps.children = children;
|
|
56
84
|
}
|
|
57
85
|
return {
|
|
58
|
-
|
|
86
|
+
// serializeJSXChildren() resolves and caches this before any element is
|
|
87
|
+
// built; the fallback only applies if createElement is ever reached first.
|
|
88
|
+
$$typeof: cachedReactElementType ?? Symbol.for('react.transitional.element'),
|
|
59
89
|
type,
|
|
60
90
|
props: finalProps,
|
|
61
91
|
key: null,
|
|
@@ -458,11 +488,19 @@ function childrenHaveInlineCount(children) {
|
|
|
458
488
|
return false;
|
|
459
489
|
}
|
|
460
490
|
function serializeJSXChildren(children, config) {
|
|
461
|
-
const
|
|
491
|
+
const rt = loadReactI18next();
|
|
492
|
+
if (!rt) {
|
|
493
|
+
warnReactI18nextUnavailable();
|
|
494
|
+
return '';
|
|
495
|
+
}
|
|
496
|
+
// Resolve the element `$$typeof` before swcChildrenToReactNodes() builds any
|
|
497
|
+
// elements via createElement().
|
|
498
|
+
resolveReactElementType(rt);
|
|
499
|
+
const i18nextOptions = { ...rt.getDefaults() };
|
|
462
500
|
if (config.extract.transKeepBasicHtmlNodesFor) {
|
|
463
501
|
i18nextOptions.transKeepBasicHtmlNodesFor = config.extract.transKeepBasicHtmlNodesFor;
|
|
464
502
|
}
|
|
465
|
-
return nodesToString(swcChildrenToReactNodes(children), i18nextOptions);
|
|
503
|
+
return rt.nodesToString(swcChildrenToReactNodes(children), i18nextOptions);
|
|
466
504
|
}
|
|
467
505
|
|
|
468
506
|
export { extractFromTransComponent };
|
package/dist/esm/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { defineConfig } from './config.js';
|
|
|
2
2
|
export { extract, runExtractor } from './extractor/core/extractor.js';
|
|
3
3
|
export { findKeys } from './extractor/core/key-finder.js';
|
|
4
4
|
export { getTranslations } from './extractor/core/translation-manager.js';
|
|
5
|
-
import '
|
|
5
|
+
import 'node:module';
|
|
6
6
|
export { recommendedAcceptedAttributes, recommendedAcceptedTags, runLinter } from './linter.js';
|
|
7
7
|
export { runSyncer } from './syncer.js';
|
|
8
8
|
export { runStatus } from './status.js';
|
package/dist/esm/status.js
CHANGED
|
@@ -11,7 +11,7 @@ import { safePluralRules } from './utils/plural-rules.js';
|
|
|
11
11
|
import { parseNestedReferences } from './utils/nesting.js';
|
|
12
12
|
import { isContextVariantOfAcceptingKey } from './utils/context-variants.js';
|
|
13
13
|
import { shouldShowFunnel, recordFunnelShown } from './utils/funnel-msg-tracker.js';
|
|
14
|
-
import '
|
|
14
|
+
import 'node:module';
|
|
15
15
|
|
|
16
16
|
function classifyValue(value) {
|
|
17
17
|
if (value === undefined || value === null)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18next-cli",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.3",
|
|
4
4
|
"description": "A unified, high-performance i18next CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -59,16 +59,16 @@
|
|
|
59
59
|
"@types/node": "^25.9.1",
|
|
60
60
|
"@types/react": "^19.2.15",
|
|
61
61
|
"@typescript-eslint/parser": "^8.60.0",
|
|
62
|
-
"@vitest/coverage-v8": "^4.1.
|
|
62
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
63
63
|
"eslint": "^9.39.4",
|
|
64
|
-
"eslint-import-resolver-typescript": "^4.4.
|
|
64
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
65
65
|
"eslint-plugin-import": "^2.32.0",
|
|
66
66
|
"memfs": "^4.57.3",
|
|
67
67
|
"neostandard": "^0.13.0",
|
|
68
|
-
"rollup": "^4.
|
|
68
|
+
"rollup": "^4.61.0",
|
|
69
69
|
"typescript": "^6.0.3",
|
|
70
70
|
"unplugin-swc": "^1.5.9",
|
|
71
|
-
"vitest": "^4.1.
|
|
71
|
+
"vitest": "^4.1.8"
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@croct/json5-parser": "^0.2.2",
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"commander": "^14.0.3",
|
|
78
78
|
"execa": "^9.6.1",
|
|
79
79
|
"glob": "^13.0.6",
|
|
80
|
+
"i18next": "^26.3.0",
|
|
80
81
|
"i18next-resources-for-ts": "^2.1.0",
|
|
81
82
|
"inquirer": "^13.4.3",
|
|
82
83
|
"jiti": "^2.7.0",
|
|
@@ -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,gBAAgB,CAAA;
|
|
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,gBAAgB,CAAA;AAkH1D,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"}
|