i18next-cli 1.46.2 → 1.46.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
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.46.
|
|
31
|
+
.version('1.46.3'); // 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
|
|
@@ -98,18 +98,13 @@ function hasEmptySegments(key, separator) {
|
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Detects a nesting conflict for `key` against the object being built.
|
|
101
|
+
* Returns the conflicting ancestor/descendant key path as a string when a
|
|
102
|
+
* conflict is found, or `null` when there is no conflict.
|
|
101
103
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* (we cannot descend into a string to set a child).
|
|
105
|
-
* - A parent of a segment in `key` would clobber an existing sub-tree
|
|
106
|
-
* (the key itself resolves to an object but a new leaf is about to overwrite it
|
|
107
|
-
* and the object already has children from a deeper extracted key).
|
|
108
|
-
*
|
|
109
|
-
* In both cases the caller should skip the conflicting key rather than producing
|
|
110
|
-
* a silently-wrong flat fallback.
|
|
104
|
+
* The returned string lets callers produce an actionable error message
|
|
105
|
+
* pointing to the specific key that is already occupying the conflicting path.
|
|
111
106
|
*/
|
|
112
|
-
function
|
|
107
|
+
function findNestingConflict(obj, key, separator) {
|
|
113
108
|
const parts = key.split(separator);
|
|
114
109
|
let current = obj;
|
|
115
110
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
@@ -117,12 +112,12 @@ function hasNestingConflict(obj, key, separator) {
|
|
|
117
112
|
const value = current[part];
|
|
118
113
|
if (value === undefined || value === null) {
|
|
119
114
|
// Path does not exist yet — no conflict
|
|
120
|
-
return
|
|
115
|
+
return null;
|
|
121
116
|
}
|
|
122
117
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
123
118
|
// A non-object value already occupies an ancestor segment.
|
|
124
119
|
// We cannot nest inside a string/number/array.
|
|
125
|
-
return
|
|
120
|
+
return parts.slice(0, i + 1).join(separator);
|
|
126
121
|
}
|
|
127
122
|
current = value;
|
|
128
123
|
}
|
|
@@ -132,9 +127,10 @@ function hasNestingConflict(obj, key, separator) {
|
|
|
132
127
|
const leafPart = parts[parts.length - 1];
|
|
133
128
|
const leafValue = current[leafPart];
|
|
134
129
|
if (typeof leafValue === 'object' && leafValue !== null && !Array.isArray(leafValue) && Object.keys(leafValue).length > 0) {
|
|
135
|
-
|
|
130
|
+
// The conflicting path is the key itself (it already has nested children)
|
|
131
|
+
return key;
|
|
136
132
|
}
|
|
137
|
-
return
|
|
133
|
+
return null;
|
|
138
134
|
}
|
|
139
135
|
/**
|
|
140
136
|
* Recursively sorts the keys of an object.
|
|
@@ -698,14 +694,16 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
698
694
|
// that was already written by a different extracted key, e.g.:
|
|
699
695
|
// t("a.b") => sets a.b = string
|
|
700
696
|
// t("a.b.c") => tries to descend into a.b which is already a string
|
|
701
|
-
// In that situation we skip the conflicting key
|
|
702
|
-
//
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
697
|
+
// In that situation we skip the conflicting key and emit a console.error so
|
|
698
|
+
// developers see the problem immediately — a skipped key becomes a missing
|
|
699
|
+
// translation at runtime.
|
|
700
|
+
if (separator && typeof separator === 'string') {
|
|
701
|
+
const conflictingPath = findNestingConflict(newTranslations, key, separator);
|
|
702
|
+
if (conflictingPath !== null) {
|
|
703
|
+
console.error(`[i18next-toolkit] Nesting conflict: key "${key}" conflicts with existing key "${conflictingPath}". ` +
|
|
704
|
+
`"${key}" will be skipped — fix the overlapping key paths in your source code to avoid missing translations at runtime.`);
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
709
707
|
}
|
|
710
708
|
nestedObject.setNestedValue(newTranslations, key, valueToSet, separator);
|
|
711
709
|
}
|
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.46.
|
|
29
|
+
.version('1.46.3'); // 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
|
|
@@ -96,18 +96,13 @@ function hasEmptySegments(key, separator) {
|
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Detects a nesting conflict for `key` against the object being built.
|
|
99
|
+
* Returns the conflicting ancestor/descendant key path as a string when a
|
|
100
|
+
* conflict is found, or `null` when there is no conflict.
|
|
99
101
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* (we cannot descend into a string to set a child).
|
|
103
|
-
* - A parent of a segment in `key` would clobber an existing sub-tree
|
|
104
|
-
* (the key itself resolves to an object but a new leaf is about to overwrite it
|
|
105
|
-
* and the object already has children from a deeper extracted key).
|
|
106
|
-
*
|
|
107
|
-
* In both cases the caller should skip the conflicting key rather than producing
|
|
108
|
-
* a silently-wrong flat fallback.
|
|
102
|
+
* The returned string lets callers produce an actionable error message
|
|
103
|
+
* pointing to the specific key that is already occupying the conflicting path.
|
|
109
104
|
*/
|
|
110
|
-
function
|
|
105
|
+
function findNestingConflict(obj, key, separator) {
|
|
111
106
|
const parts = key.split(separator);
|
|
112
107
|
let current = obj;
|
|
113
108
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
@@ -115,12 +110,12 @@ function hasNestingConflict(obj, key, separator) {
|
|
|
115
110
|
const value = current[part];
|
|
116
111
|
if (value === undefined || value === null) {
|
|
117
112
|
// Path does not exist yet — no conflict
|
|
118
|
-
return
|
|
113
|
+
return null;
|
|
119
114
|
}
|
|
120
115
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
121
116
|
// A non-object value already occupies an ancestor segment.
|
|
122
117
|
// We cannot nest inside a string/number/array.
|
|
123
|
-
return
|
|
118
|
+
return parts.slice(0, i + 1).join(separator);
|
|
124
119
|
}
|
|
125
120
|
current = value;
|
|
126
121
|
}
|
|
@@ -130,9 +125,10 @@ function hasNestingConflict(obj, key, separator) {
|
|
|
130
125
|
const leafPart = parts[parts.length - 1];
|
|
131
126
|
const leafValue = current[leafPart];
|
|
132
127
|
if (typeof leafValue === 'object' && leafValue !== null && !Array.isArray(leafValue) && Object.keys(leafValue).length > 0) {
|
|
133
|
-
|
|
128
|
+
// The conflicting path is the key itself (it already has nested children)
|
|
129
|
+
return key;
|
|
134
130
|
}
|
|
135
|
-
return
|
|
131
|
+
return null;
|
|
136
132
|
}
|
|
137
133
|
/**
|
|
138
134
|
* Recursively sorts the keys of an object.
|
|
@@ -696,14 +692,16 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
696
692
|
// that was already written by a different extracted key, e.g.:
|
|
697
693
|
// t("a.b") => sets a.b = string
|
|
698
694
|
// t("a.b.c") => tries to descend into a.b which is already a string
|
|
699
|
-
// In that situation we skip the conflicting key
|
|
700
|
-
//
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
695
|
+
// In that situation we skip the conflicting key and emit a console.error so
|
|
696
|
+
// developers see the problem immediately — a skipped key becomes a missing
|
|
697
|
+
// translation at runtime.
|
|
698
|
+
if (separator && typeof separator === 'string') {
|
|
699
|
+
const conflictingPath = findNestingConflict(newTranslations, key, separator);
|
|
700
|
+
if (conflictingPath !== null) {
|
|
701
|
+
console.error(`[i18next-toolkit] Nesting conflict: key "${key}" conflicts with existing key "${conflictingPath}". ` +
|
|
702
|
+
`"${key}" will be skipped — fix the overlapping key paths in your source code to avoid missing translations at runtime.`);
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
707
705
|
}
|
|
708
706
|
setNestedValue(newTranslations, key, valueToSet, separator);
|
|
709
707
|
}
|