i18next-cli 1.46.3 → 1.46.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.
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/extractor/core/extractor.js +2 -1
- package/dist/cjs/extractor/core/translation-manager.js +8 -7
- package/dist/esm/cli.js +1 -1
- package/dist/esm/extractor/core/extractor.js +2 -1
- package/dist/esm/extractor/core/translation-manager.js +8 -7
- package/package.json +1 -1
- package/types/extractor/core/extractor.d.ts.map +1 -1
- package/types/extractor/core/translation-manager.d.ts +3 -2
- package/types/extractor/core/translation-manager.d.ts.map +1 -1
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.4'); // 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
|
|
@@ -57,7 +57,8 @@ async function runExtractor(config, options = {}) {
|
|
|
57
57
|
spinner.text = `Found ${allKeys.size} unique keys. Updating translation files...`;
|
|
58
58
|
const results = await translationManager.getTranslations(allKeys, objectKeys, config, {
|
|
59
59
|
syncPrimaryWithDefaults: options.syncPrimaryWithDefaults,
|
|
60
|
-
syncAll: options.syncAll
|
|
60
|
+
syncAll: options.syncAll,
|
|
61
|
+
logger: options.logger
|
|
61
62
|
});
|
|
62
63
|
let anyFileUpdated = false;
|
|
63
64
|
for (const result of results) {
|
|
@@ -5,6 +5,7 @@ var glob = require('glob');
|
|
|
5
5
|
var nestedObject = require('../../utils/nested-object.js');
|
|
6
6
|
var fileUtils = require('../../utils/file-utils.js');
|
|
7
7
|
var defaultValue = require('../../utils/default-value.js');
|
|
8
|
+
var logger = require('../../utils/logger.js');
|
|
8
9
|
|
|
9
10
|
// used for natural language check
|
|
10
11
|
const chars = [' ', ',', '?', '!', ';'];
|
|
@@ -208,7 +209,7 @@ function sortObject(obj, config, customSort) {
|
|
|
208
209
|
* A helper function to build a new translation object for a single namespace.
|
|
209
210
|
* This centralizes the core logic of merging keys.
|
|
210
211
|
*/
|
|
211
|
-
function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, namespace, preservePatterns = [], objectKeys = new Set(), syncPrimaryWithDefaults = false, syncAll = false) {
|
|
212
|
+
function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, namespace, preservePatterns = [], objectKeys = new Set(), syncPrimaryWithDefaults = false, syncAll = false, logger$1 = new logger.ConsoleLogger()) {
|
|
212
213
|
const { keySeparator = '.', sort = true, removeUnusedKeys = true, primaryLanguage, defaultValue: emptyDefaultValue = '', pluralSeparator = '_', contextSeparator = '_', preserveContextVariants = false, } = config.extract;
|
|
213
214
|
const nsSep = typeof config.extract.nsSeparator === 'string' ? config.extract.nsSeparator : ':';
|
|
214
215
|
// Keep the raw configured defaultValue so we can distinguish:
|
|
@@ -694,13 +695,13 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
694
695
|
// that was already written by a different extracted key, e.g.:
|
|
695
696
|
// t("a.b") => sets a.b = string
|
|
696
697
|
// t("a.b.c") => tries to descend into a.b which is already a string
|
|
697
|
-
// In that situation we skip the conflicting key and emit a
|
|
698
|
+
// In that situation we skip the conflicting key and emit a log error so
|
|
698
699
|
// developers see the problem immediately — a skipped key becomes a missing
|
|
699
700
|
// translation at runtime.
|
|
700
701
|
if (separator && typeof separator === 'string') {
|
|
701
702
|
const conflictingPath = findNestingConflict(newTranslations, key, separator);
|
|
702
703
|
if (conflictingPath !== null) {
|
|
703
|
-
|
|
704
|
+
logger$1.error(`Nesting conflict: key "${key}" conflicts with existing key "${conflictingPath}". ` +
|
|
704
705
|
`"${key}" will be skipped — fix the overlapping key paths in your source code to avoid missing translations at runtime.`);
|
|
705
706
|
continue;
|
|
706
707
|
}
|
|
@@ -784,7 +785,7 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
784
785
|
* // Results contain update status and new/existing translations for each locale.
|
|
785
786
|
* ```
|
|
786
787
|
*/
|
|
787
|
-
async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaults = false, syncAll = false } = {}) {
|
|
788
|
+
async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaults = false, syncAll = false, logger: logger$1 = new logger.ConsoleLogger() } = {}) {
|
|
788
789
|
config.extract.primaryLanguage ||= config.locales[0] || 'en';
|
|
789
790
|
config.extract.secondaryLanguages ||= config.locales.filter((l) => l !== config?.extract?.primaryLanguage);
|
|
790
791
|
const patternsToPreserve = [...(config.extract.preservePatterns || [])];
|
|
@@ -872,12 +873,12 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
|
|
|
872
873
|
const nsKeys = keysByNS.get(nsKey) || [];
|
|
873
874
|
if (nsKey === NO_NS_TOKEN) {
|
|
874
875
|
// keys without namespace -> merged into top-level of the merged file
|
|
875
|
-
const built = buildNewTranslationsForNs(nsKeys, existingMergedFile, config, locale, undefined, preservePatterns, objectKeys, syncPrimaryWithDefaults);
|
|
876
|
+
const built = buildNewTranslationsForNs(nsKeys, existingMergedFile, config, locale, undefined, preservePatterns, objectKeys, syncPrimaryWithDefaults, undefined, logger$1);
|
|
876
877
|
Object.assign(newMergedTranslations, built);
|
|
877
878
|
}
|
|
878
879
|
else {
|
|
879
880
|
const existingTranslations = existingMergedFile[nsKey] || {};
|
|
880
|
-
newMergedTranslations[nsKey] = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, nsKey, preservePatterns, objectKeys, syncPrimaryWithDefaults);
|
|
881
|
+
newMergedTranslations[nsKey] = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, nsKey, preservePatterns, objectKeys, syncPrimaryWithDefaults, undefined, logger$1);
|
|
881
882
|
}
|
|
882
883
|
}
|
|
883
884
|
// Preserve ignored namespaces as-is from the existing merged file
|
|
@@ -915,7 +916,7 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
|
|
|
915
916
|
const outputPath = fileUtils.getOutputPath(config.extract.output, locale, ns);
|
|
916
917
|
const fullPath = node_path.resolve(process.cwd(), outputPath);
|
|
917
918
|
const existingTranslations = await fileUtils.loadTranslationFile(fullPath) || {};
|
|
918
|
-
const newTranslations = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, ns, preservePatterns, objectKeys, syncPrimaryWithDefaults, syncAll);
|
|
919
|
+
const newTranslations = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, ns, preservePatterns, objectKeys, syncPrimaryWithDefaults, syncAll, logger$1);
|
|
919
920
|
const oldContent = JSON.stringify(existingTranslations, null, indentation);
|
|
920
921
|
const newContent = JSON.stringify(newTranslations, null, indentation);
|
|
921
922
|
// Push one result per namespace file
|
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.4'); // 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
|
|
@@ -55,7 +55,8 @@ async function runExtractor(config, options = {}) {
|
|
|
55
55
|
spinner.text = `Found ${allKeys.size} unique keys. Updating translation files...`;
|
|
56
56
|
const results = await getTranslations(allKeys, objectKeys, config, {
|
|
57
57
|
syncPrimaryWithDefaults: options.syncPrimaryWithDefaults,
|
|
58
|
-
syncAll: options.syncAll
|
|
58
|
+
syncAll: options.syncAll,
|
|
59
|
+
logger: options.logger
|
|
59
60
|
});
|
|
60
61
|
let anyFileUpdated = false;
|
|
61
62
|
for (const result of results) {
|
|
@@ -3,6 +3,7 @@ import { glob } from 'glob';
|
|
|
3
3
|
import { getNestedKeys, getNestedValue, setNestedValue } from '../../utils/nested-object.js';
|
|
4
4
|
import { getOutputPath, loadTranslationFile } from '../../utils/file-utils.js';
|
|
5
5
|
import { resolveDefaultValue } from '../../utils/default-value.js';
|
|
6
|
+
import { ConsoleLogger } from '../../utils/logger.js';
|
|
6
7
|
|
|
7
8
|
// used for natural language check
|
|
8
9
|
const chars = [' ', ',', '?', '!', ';'];
|
|
@@ -206,7 +207,7 @@ function sortObject(obj, config, customSort) {
|
|
|
206
207
|
* A helper function to build a new translation object for a single namespace.
|
|
207
208
|
* This centralizes the core logic of merging keys.
|
|
208
209
|
*/
|
|
209
|
-
function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, namespace, preservePatterns = [], objectKeys = new Set(), syncPrimaryWithDefaults = false, syncAll = false) {
|
|
210
|
+
function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, namespace, preservePatterns = [], objectKeys = new Set(), syncPrimaryWithDefaults = false, syncAll = false, logger = new ConsoleLogger()) {
|
|
210
211
|
const { keySeparator = '.', sort = true, removeUnusedKeys = true, primaryLanguage, defaultValue: emptyDefaultValue = '', pluralSeparator = '_', contextSeparator = '_', preserveContextVariants = false, } = config.extract;
|
|
211
212
|
const nsSep = typeof config.extract.nsSeparator === 'string' ? config.extract.nsSeparator : ':';
|
|
212
213
|
// Keep the raw configured defaultValue so we can distinguish:
|
|
@@ -692,13 +693,13 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
692
693
|
// that was already written by a different extracted key, e.g.:
|
|
693
694
|
// t("a.b") => sets a.b = string
|
|
694
695
|
// t("a.b.c") => tries to descend into a.b which is already a string
|
|
695
|
-
// In that situation we skip the conflicting key and emit a
|
|
696
|
+
// In that situation we skip the conflicting key and emit a log error so
|
|
696
697
|
// developers see the problem immediately — a skipped key becomes a missing
|
|
697
698
|
// translation at runtime.
|
|
698
699
|
if (separator && typeof separator === 'string') {
|
|
699
700
|
const conflictingPath = findNestingConflict(newTranslations, key, separator);
|
|
700
701
|
if (conflictingPath !== null) {
|
|
701
|
-
|
|
702
|
+
logger.error(`Nesting conflict: key "${key}" conflicts with existing key "${conflictingPath}". ` +
|
|
702
703
|
`"${key}" will be skipped — fix the overlapping key paths in your source code to avoid missing translations at runtime.`);
|
|
703
704
|
continue;
|
|
704
705
|
}
|
|
@@ -782,7 +783,7 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
782
783
|
* // Results contain update status and new/existing translations for each locale.
|
|
783
784
|
* ```
|
|
784
785
|
*/
|
|
785
|
-
async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaults = false, syncAll = false } = {}) {
|
|
786
|
+
async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaults = false, syncAll = false, logger = new ConsoleLogger() } = {}) {
|
|
786
787
|
config.extract.primaryLanguage ||= config.locales[0] || 'en';
|
|
787
788
|
config.extract.secondaryLanguages ||= config.locales.filter((l) => l !== config?.extract?.primaryLanguage);
|
|
788
789
|
const patternsToPreserve = [...(config.extract.preservePatterns || [])];
|
|
@@ -870,12 +871,12 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
|
|
|
870
871
|
const nsKeys = keysByNS.get(nsKey) || [];
|
|
871
872
|
if (nsKey === NO_NS_TOKEN) {
|
|
872
873
|
// keys without namespace -> merged into top-level of the merged file
|
|
873
|
-
const built = buildNewTranslationsForNs(nsKeys, existingMergedFile, config, locale, undefined, preservePatterns, objectKeys, syncPrimaryWithDefaults);
|
|
874
|
+
const built = buildNewTranslationsForNs(nsKeys, existingMergedFile, config, locale, undefined, preservePatterns, objectKeys, syncPrimaryWithDefaults, undefined, logger);
|
|
874
875
|
Object.assign(newMergedTranslations, built);
|
|
875
876
|
}
|
|
876
877
|
else {
|
|
877
878
|
const existingTranslations = existingMergedFile[nsKey] || {};
|
|
878
|
-
newMergedTranslations[nsKey] = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, nsKey, preservePatterns, objectKeys, syncPrimaryWithDefaults);
|
|
879
|
+
newMergedTranslations[nsKey] = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, nsKey, preservePatterns, objectKeys, syncPrimaryWithDefaults, undefined, logger);
|
|
879
880
|
}
|
|
880
881
|
}
|
|
881
882
|
// Preserve ignored namespaces as-is from the existing merged file
|
|
@@ -913,7 +914,7 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
|
|
|
913
914
|
const outputPath = getOutputPath(config.extract.output, locale, ns);
|
|
914
915
|
const fullPath = resolve(process.cwd(), outputPath);
|
|
915
916
|
const existingTranslations = await loadTranslationFile(fullPath) || {};
|
|
916
|
-
const newTranslations = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, ns, preservePatterns, objectKeys, syncPrimaryWithDefaults, syncAll);
|
|
917
|
+
const newTranslations = buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale, ns, preservePatterns, objectKeys, syncPrimaryWithDefaults, syncAll, logger);
|
|
917
918
|
const oldContent = JSON.stringify(existingTranslations, null, indentation);
|
|
918
919
|
const newContent = JSON.stringify(newTranslations, null, indentation);
|
|
919
920
|
// Push one result per namespace file
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/extractor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAMtF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAK5C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CACX,GACL,OAAO,CAAC;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/extractor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAMtF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAK5C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CACX,GACL,OAAO,CAAC;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAuE1D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE,EACjB,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,MAAM,GAAE,MAA4B,EACpC,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC,CA8Gf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,OAAO,CAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,uBAA+B,EAAE,GAAE;IAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAO,sDAO3I"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TranslationResult, ExtractedKey, I18nextToolkitConfig } from '../../types';
|
|
1
|
+
import { TranslationResult, ExtractedKey, I18nextToolkitConfig, Logger } from '../../types';
|
|
2
2
|
/**
|
|
3
3
|
* Processes extracted translation keys and generates translation files for all configured locales.
|
|
4
4
|
*
|
|
@@ -28,8 +28,9 @@ import { TranslationResult, ExtractedKey, I18nextToolkitConfig } from '../../typ
|
|
|
28
28
|
* // Results contain update status and new/existing translations for each locale.
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
|
-
export declare function getTranslations(keys: Map<string, ExtractedKey>, objectKeys: Set<string>, config: I18nextToolkitConfig, { syncPrimaryWithDefaults, syncAll }?: {
|
|
31
|
+
export declare function getTranslations(keys: Map<string, ExtractedKey>, objectKeys: Set<string>, config: I18nextToolkitConfig, { syncPrimaryWithDefaults, syncAll, logger }?: {
|
|
32
32
|
syncPrimaryWithDefaults?: boolean;
|
|
33
33
|
syncAll?: boolean;
|
|
34
|
+
logger?: Logger;
|
|
34
35
|
}): Promise<TranslationResult[]>;
|
|
35
36
|
//# sourceMappingURL=translation-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAg3B3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,oBAAoB,EAC5B,EACE,uBAA+B,EAC/B,OAAe,EACf,MAA4B,EAC7B,GAAE;IACD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CACX,GACL,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA8J9B"}
|