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 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.3'); // This string is replaced with the actual version at build time by rollup
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 console.error so
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
- console.error(`[i18next-toolkit] Nesting conflict: key "${key}" conflicts with existing key "${conflictingPath}". ` +
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.3'); // This string is replaced with the actual version at build time by rollup
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 console.error so
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
- console.error(`[i18next-toolkit] Nesting conflict: key "${key}" conflicts with existing key "${conflictingPath}". ` +
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,6 +1,6 @@
1
1
  {
2
2
  "name": "i18next-cli",
3
- "version": "1.46.3",
3
+ "version": "1.46.4",
4
4
  "description": "A unified, high-performance i18next CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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,CAsE1D;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
+ {"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;AA82BnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,EAChB,GAAE;IACD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAA;CACb,GACL,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA8J9B"}
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"}