i18next-cli 1.44.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/README.md CHANGED
@@ -1138,8 +1138,8 @@ const config: I18nextToolkitConfig = {
1138
1138
  };
1139
1139
 
1140
1140
  // Run the complete extraction process
1141
- const wasUpdated = await runExtractor(config);
1142
- console.log('Files updated:', wasUpdated);
1141
+ const { anyFileUpdated, hasErrors } = await runExtractor(config);
1142
+ console.log('Files updated:', anyFileUpdated);
1143
1143
 
1144
1144
  // Check translation status programmatically
1145
1145
  await runStatus(config);
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.44.0'); // This string is replaced with the actual version at build time by rollup
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
@@ -47,22 +47,25 @@ program
47
47
  const runExtract = async () => {
48
48
  // --sync-all implies sync-primary behavior
49
49
  const syncPrimary = !!options.syncPrimary || !!options.syncAll;
50
- const success = await extractor.runExtractor(config$1, {
50
+ const { anyFileUpdated, hasErrors } = await extractor.runExtractor(config$1, {
51
51
  isWatchMode: !!options.watch,
52
52
  isDryRun: !!options.dryRun,
53
53
  syncPrimaryWithDefaults: syncPrimary,
54
54
  syncAll: !!options.syncAll,
55
55
  quiet: !!options.quiet
56
56
  });
57
- if (options.ci && !success) {
57
+ if (options.ci && !anyFileUpdated) {
58
58
  console.log('✅ No files were updated.');
59
- process.exit(0);
59
+ process.exit(hasErrors ? 1 : 0);
60
60
  }
61
- else if (options.ci && success) {
61
+ else if (options.ci && anyFileUpdated) {
62
62
  console.error('❌ Some files were updated. This should not happen in CI mode.');
63
63
  process.exit(1);
64
64
  }
65
- return success;
65
+ if (hasErrors && !options.watch) {
66
+ process.exit(1);
67
+ }
68
+ return anyFileUpdated;
66
69
  };
67
70
  // Run the extractor once initially
68
71
  await runExtract();
@@ -52,7 +52,8 @@ async function runExtractor(config, options = {}) {
52
52
  // Only pass logger to spinner if explicitly provided
53
53
  const spinner = wrapOra.createSpinnerLike('Running i18next key extractor...\n', { quiet: !!options.quiet, logger: options.logger });
54
54
  try {
55
- const { allKeys, objectKeys } = await keyFinder.findKeys(config, internalLogger);
55
+ const fileErrors = [];
56
+ const { allKeys, objectKeys } = await keyFinder.findKeys(config, internalLogger, fileErrors);
56
57
  spinner.text = `Found ${allKeys.size} unique keys. Updating translation files...`;
57
58
  const results = await translationManager.getTranslations(allKeys, objectKeys, config, {
58
59
  syncPrimaryWithDefaults: options.syncPrimaryWithDefaults,
@@ -82,11 +83,14 @@ async function runExtractor(config, options = {}) {
82
83
  await plugin.afterSync?.(results, config);
83
84
  }
84
85
  }
85
- spinner.succeed(node_util.styleText('bold', 'Extraction complete!'));
86
+ const completionMessage = fileErrors.length > 0
87
+ ? node_util.styleText('bold', `Extraction complete, but ignored ${fileErrors.length} file${fileErrors.length === 1 ? '' : 's'}!`)
88
+ : node_util.styleText('bold', 'Extraction complete!');
89
+ spinner.succeed(completionMessage);
86
90
  // Show the funnel message only if files were actually changed.
87
91
  if (anyFileUpdated)
88
92
  await printLocizeFunnel(options.logger);
89
- return anyFileUpdated;
93
+ return { anyFileUpdated, hasErrors: fileErrors.length > 0 };
90
94
  }
91
95
  catch (error) {
92
96
  spinner.fail(node_util.styleText('red', 'Extraction failed.'));
@@ -114,7 +118,7 @@ async function runExtractor(config, options = {}) {
114
118
  *
115
119
  * @internal
116
120
  */
117
- async function processFile(file, plugins, astVisitors, pluginContext, config, logger$1 = new logger.ConsoleLogger()) {
121
+ async function processFile(file, plugins, astVisitors, pluginContext, config, logger$1 = new logger.ConsoleLogger(), fileErrors) {
118
122
  try {
119
123
  let code = await promises.readFile(file, 'utf-8');
120
124
  // Run onLoad hooks from plugins with error handling
@@ -215,6 +219,8 @@ async function processFile(file, plugins, astVisitors, pluginContext, config, lo
215
219
  if ((!err?.message || String(err.message).trim() === '') && err?.stack) {
216
220
  logger$1.warn(` ${String(err.stack)}`);
217
221
  }
222
+ // Record the failure so callers can exit non-zero even though we continue extraction
223
+ fileErrors?.push(file);
218
224
  }
219
225
  }
220
226
  /**
@@ -35,7 +35,7 @@ var expressionResolver = require('../parsers/expression-resolver.js');
35
35
  * console.log(`Found ${keys.size} unique translation keys`)
36
36
  * ```
37
37
  */
38
- async function findKeys(config, logger$1 = new logger.ConsoleLogger()) {
38
+ async function findKeys(config, logger$1 = new logger.ConsoleLogger(), fileErrors) {
39
39
  const { plugins: pluginsOrUndefined, ...otherConfig } = config;
40
40
  const plugins = pluginsOrUndefined || [];
41
41
  const sourceFiles = await processSourceFiles(config);
@@ -88,7 +88,7 @@ async function findKeys(config, logger$1 = new logger.ConsoleLogger()) {
88
88
  await pluginManager.initializePlugins(plugins);
89
89
  // 6. Process each file
90
90
  for (const file of sourceFiles) {
91
- await extractor.processFile(file, plugins, astVisitors$1, pluginContext, otherConfig, logger$1);
91
+ await extractor.processFile(file, plugins, astVisitors$1, pluginContext, otherConfig, logger$1, fileErrors);
92
92
  }
93
93
  // 7. Run onEnd hooks
94
94
  for (const plugin of plugins) {
@@ -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
- const hasCount = !!countAttr || !!valuesCountProperty;
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.44.0'); // This string is replaced with the actual version at build time by rollup
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
@@ -45,22 +45,25 @@ program
45
45
  const runExtract = async () => {
46
46
  // --sync-all implies sync-primary behavior
47
47
  const syncPrimary = !!options.syncPrimary || !!options.syncAll;
48
- const success = await runExtractor(config, {
48
+ const { anyFileUpdated, hasErrors } = await runExtractor(config, {
49
49
  isWatchMode: !!options.watch,
50
50
  isDryRun: !!options.dryRun,
51
51
  syncPrimaryWithDefaults: syncPrimary,
52
52
  syncAll: !!options.syncAll,
53
53
  quiet: !!options.quiet
54
54
  });
55
- if (options.ci && !success) {
55
+ if (options.ci && !anyFileUpdated) {
56
56
  console.log('✅ No files were updated.');
57
- process.exit(0);
57
+ process.exit(hasErrors ? 1 : 0);
58
58
  }
59
- else if (options.ci && success) {
59
+ else if (options.ci && anyFileUpdated) {
60
60
  console.error('❌ Some files were updated. This should not happen in CI mode.');
61
61
  process.exit(1);
62
62
  }
63
- return success;
63
+ if (hasErrors && !options.watch) {
64
+ process.exit(1);
65
+ }
66
+ return anyFileUpdated;
64
67
  };
65
68
  // Run the extractor once initially
66
69
  await runExtract();
@@ -50,7 +50,8 @@ async function runExtractor(config, options = {}) {
50
50
  // Only pass logger to spinner if explicitly provided
51
51
  const spinner = createSpinnerLike('Running i18next key extractor...\n', { quiet: !!options.quiet, logger: options.logger });
52
52
  try {
53
- const { allKeys, objectKeys } = await findKeys(config, internalLogger);
53
+ const fileErrors = [];
54
+ const { allKeys, objectKeys } = await findKeys(config, internalLogger, fileErrors);
54
55
  spinner.text = `Found ${allKeys.size} unique keys. Updating translation files...`;
55
56
  const results = await getTranslations(allKeys, objectKeys, config, {
56
57
  syncPrimaryWithDefaults: options.syncPrimaryWithDefaults,
@@ -80,11 +81,14 @@ async function runExtractor(config, options = {}) {
80
81
  await plugin.afterSync?.(results, config);
81
82
  }
82
83
  }
83
- spinner.succeed(styleText('bold', 'Extraction complete!'));
84
+ const completionMessage = fileErrors.length > 0
85
+ ? styleText('bold', `Extraction complete, but ignored ${fileErrors.length} file${fileErrors.length === 1 ? '' : 's'}!`)
86
+ : styleText('bold', 'Extraction complete!');
87
+ spinner.succeed(completionMessage);
84
88
  // Show the funnel message only if files were actually changed.
85
89
  if (anyFileUpdated)
86
90
  await printLocizeFunnel(options.logger);
87
- return anyFileUpdated;
91
+ return { anyFileUpdated, hasErrors: fileErrors.length > 0 };
88
92
  }
89
93
  catch (error) {
90
94
  spinner.fail(styleText('red', 'Extraction failed.'));
@@ -112,7 +116,7 @@ async function runExtractor(config, options = {}) {
112
116
  *
113
117
  * @internal
114
118
  */
115
- async function processFile(file, plugins, astVisitors, pluginContext, config, logger = new ConsoleLogger()) {
119
+ async function processFile(file, plugins, astVisitors, pluginContext, config, logger = new ConsoleLogger(), fileErrors) {
116
120
  try {
117
121
  let code = await readFile(file, 'utf-8');
118
122
  // Run onLoad hooks from plugins with error handling
@@ -213,6 +217,8 @@ async function processFile(file, plugins, astVisitors, pluginContext, config, lo
213
217
  if ((!err?.message || String(err.message).trim() === '') && err?.stack) {
214
218
  logger.warn(` ${String(err.stack)}`);
215
219
  }
220
+ // Record the failure so callers can exit non-zero even though we continue extraction
221
+ fileErrors?.push(file);
216
222
  }
217
223
  }
218
224
  /**
@@ -33,7 +33,7 @@ import { ExpressionResolver } from '../parsers/expression-resolver.js';
33
33
  * console.log(`Found ${keys.size} unique translation keys`)
34
34
  * ```
35
35
  */
36
- async function findKeys(config, logger = new ConsoleLogger()) {
36
+ async function findKeys(config, logger = new ConsoleLogger(), fileErrors) {
37
37
  const { plugins: pluginsOrUndefined, ...otherConfig } = config;
38
38
  const plugins = pluginsOrUndefined || [];
39
39
  const sourceFiles = await processSourceFiles(config);
@@ -86,7 +86,7 @@ async function findKeys(config, logger = new ConsoleLogger()) {
86
86
  await initializePlugins(plugins);
87
87
  // 6. Process each file
88
88
  for (const file of sourceFiles) {
89
- await processFile(file, plugins, astVisitors, pluginContext, otherConfig, logger);
89
+ await processFile(file, plugins, astVisitors, pluginContext, otherConfig, logger, fileErrors);
90
90
  }
91
91
  // 7. Run onEnd hooks
92
92
  for (const plugin of plugins) {
@@ -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
- const hasCount = !!countAttr || !!valuesCountProperty;
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,6 +1,6 @@
1
1
  {
2
2
  "name": "i18next-cli",
3
- "version": "1.44.0",
3
+ "version": "1.46.0",
4
4
  "description": "A unified, high-performance i18next CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBnC,QAAA,MAAM,OAAO,SAAgB,CAAA;AAqR7B,OAAO,EAAE,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBnC,QAAA,MAAM,OAAO,SAAgB,CAAA;AAyR7B,OAAO,EAAE,OAAO,EAAE,CAAA"}
@@ -33,7 +33,10 @@ export declare function runExtractor(config: I18nextToolkitConfig, options?: {
33
33
  syncAll?: boolean;
34
34
  quiet?: boolean;
35
35
  logger?: Logger;
36
- }): Promise<boolean>;
36
+ }): Promise<{
37
+ anyFileUpdated: boolean;
38
+ hasErrors: boolean;
39
+ }>;
37
40
  /**
38
41
  * Processes an individual source file for translation key extraction.
39
42
  *
@@ -54,7 +57,7 @@ export declare function runExtractor(config: I18nextToolkitConfig, options?: {
54
57
  *
55
58
  * @internal
56
59
  */
57
- export declare function processFile(file: string, plugins: Plugin[], astVisitors: ASTVisitors, pluginContext: PluginContext, config: Omit<I18nextToolkitConfig, 'plugins'>, logger?: Logger): Promise<void>;
60
+ export declare function processFile(file: string, plugins: Plugin[], astVisitors: ASTVisitors, pluginContext: PluginContext, config: Omit<I18nextToolkitConfig, 'plugins'>, logger?: Logger, fileErrors?: string[]): Promise<void>;
58
61
  /**
59
62
  * Simplified extraction function that returns translation results without file writing.
60
63
  * Used primarily for testing and programmatic access.
@@ -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,OAAO,CAAC,CAkElB;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,GACnC,OAAO,CAAC,IAAI,CAAC,CA2Gf;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,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"}
@@ -27,7 +27,7 @@ import type { ExtractedKey, Logger, I18nextToolkitConfig } from '../../types';
27
27
  * console.log(`Found ${keys.size} unique translation keys`)
28
28
  * ```
29
29
  */
30
- export declare function findKeys(config: I18nextToolkitConfig, logger?: Logger): Promise<{
30
+ export declare function findKeys(config: I18nextToolkitConfig, logger?: Logger, fileErrors?: string[]): Promise<{
31
31
  allKeys: Map<string, ExtractedKey>;
32
32
  objectKeys: Set<string>;
33
33
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"key-finder.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/key-finder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,oBAAoB,EAAmB,MAAM,aAAa,CAAA;AAO9F;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,oBAAoB,EAC5B,MAAM,GAAE,MAA4B,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CA6E1E"}
1
+ {"version":3,"file":"key-finder.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/key-finder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,oBAAoB,EAAmB,MAAM,aAAa,CAAA;AAO9F;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,oBAAoB,EAC5B,MAAM,GAAE,MAA4B,EACpC,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CA6E1E"}
@@ -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,CA2LxH"}
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"}