i18next-cli 1.50.6 → 1.50.8

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
@@ -31,7 +31,7 @@ const program = new commander.Command();
31
31
  program
32
32
  .name('i18next-cli')
33
33
  .description('A unified, high-performance i18next CLI.')
34
- .version('1.50.6'); // This string is replaced with the actual version at build time by rollup
34
+ .version('1.50.8'); // This string is replaced with the actual version at build time by rollup
35
35
  // new: global config override option
36
36
  program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
37
37
  program
@@ -6,6 +6,7 @@ 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
8
  var logger = require('../../utils/logger.js');
9
+ var pluralRules = require('../../utils/plural-rules.js');
9
10
 
10
11
  // used for natural language check
11
12
  const chars = [' ', ',', '?', '!', ';'];
@@ -264,25 +265,14 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
264
265
  }
265
266
  }
266
267
  // Get the plural categories for the target language (only used for filtering extracted keys)
268
+ // safePluralRules falls back to 'en' for non-BCP47 custom locale codes (e.g. 'E', 'F')
267
269
  const targetLanguagePluralCategories = new Set();
270
+ const cardinalRules = pluralRules.safePluralRules(locale, { type: 'cardinal' });
271
+ const ordinalRules = pluralRules.safePluralRules(locale, { type: 'ordinal' });
268
272
  // Track cardinal plural categories separately so we can special-case single-"other" languages
269
- let cardinalCategories = [];
270
- try {
271
- const cardinalRules = new Intl.PluralRules(locale, { type: 'cardinal' });
272
- const ordinalRules = new Intl.PluralRules(locale, { type: 'ordinal' });
273
- cardinalCategories = cardinalRules.resolvedOptions().pluralCategories;
274
- cardinalCategories.forEach(cat => targetLanguagePluralCategories.add(cat));
275
- ordinalRules.resolvedOptions().pluralCategories.forEach(cat => targetLanguagePluralCategories.add(`ordinal_${cat}`));
276
- }
277
- catch (e) {
278
- // Fallback to primaryLanguage (or English) if locale is invalid
279
- const fallbackLang = primaryLanguage || 'en';
280
- const cardinalRules = new Intl.PluralRules(fallbackLang, { type: 'cardinal' });
281
- const ordinalRules = new Intl.PluralRules(fallbackLang, { type: 'ordinal' });
282
- cardinalCategories = cardinalRules.resolvedOptions().pluralCategories;
283
- cardinalCategories.forEach(cat => targetLanguagePluralCategories.add(cat));
284
- ordinalRules.resolvedOptions().pluralCategories.forEach(cat => targetLanguagePluralCategories.add(`ordinal_${cat}`));
285
- }
273
+ const cardinalCategories = cardinalRules.resolvedOptions().pluralCategories;
274
+ cardinalCategories.forEach(cat => targetLanguagePluralCategories.add(cat));
275
+ ordinalRules.resolvedOptions().pluralCategories.forEach(cat => targetLanguagePluralCategories.add(`ordinal_${cat}`));
286
276
  // Prepare namespace pattern checking helpers
287
277
  const rawPreserve = config.extract.preservePatterns || [];
288
278
  // Helper to check if a key should be filtered out during extraction
@@ -836,7 +826,7 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
836
826
  const keysByNS = new Map();
837
827
  for (const k of keys.values()) {
838
828
  const ns = k.ns;
839
- const nsKey = (k.nsIsImplicit && (config.extract.defaultNS === false || config.extract.nsSeparator === false))
829
+ const nsKey = (k.nsIsImplicit && config.extract.defaultNS === false)
840
830
  ? NO_NS_TOKEN
841
831
  : String(ns ?? (config.extract.defaultNS ?? 'translation'));
842
832
  if (!keysByNS.has(nsKey))
@@ -887,9 +877,14 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
887
877
  for (const ns of ignoreNamespaces) {
888
878
  namespacesToProcess.delete(ns);
889
879
  }
880
+ // When nsSeparator is false, keys resolved to the defaultNS (e.g. from
881
+ // useTranslation() with no args) should be treated as top-level, not
882
+ // wrapped under the namespace name.
883
+ const defaultNs = String(config.extract.defaultNS ?? 'translation');
884
+ const isTopLevel = (nsKey) => nsKey === NO_NS_TOKEN || (config.extract.nsSeparator === false && nsKey === defaultNs);
890
885
  for (const nsKey of namespacesToProcess) {
891
886
  const nsKeys = keysByNS.get(nsKey) || [];
892
- if (nsKey === NO_NS_TOKEN) {
887
+ if (isTopLevel(nsKey)) {
893
888
  // keys without namespace -> merged into top-level of the merged file
894
889
  const built = buildNewTranslationsForNs(nsKeys, existingMergedFile, config, locale, undefined, preservePatterns, objectKeys, syncPrimaryWithDefaults, undefined, logger$1);
895
890
  Object.assign(newMergedTranslations, built);
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var pluralRules = require('../../utils/plural-rules.js');
3
4
  var astUtils = require('./ast-utils.js');
4
5
 
5
6
  // Helper to escape regex characters
@@ -341,7 +342,7 @@ class CallExpressionHandler {
341
342
  const primaryLang = this.config.extract?.primaryLanguage || (Array.isArray(this.config.locales) ? this.config.locales[0] : undefined) || 'en';
342
343
  let isSingleOther = false;
343
344
  try {
344
- const primaryCategories = new Intl.PluralRules(primaryLang, { type: typeForCheck }).resolvedOptions().pluralCategories;
345
+ const primaryCategories = pluralRules.safePluralRules(primaryLang, { type: typeForCheck }).resolvedOptions().pluralCategories;
345
346
  if (primaryCategories.length === 1 && primaryCategories[0] === 'other') {
346
347
  isSingleOther = true;
347
348
  }
@@ -353,11 +354,11 @@ class CallExpressionHandler {
353
354
  const allPluralCategoriesCheck = new Set();
354
355
  for (const locale of this.config.locales) {
355
356
  try {
356
- const rules = new Intl.PluralRules(locale, { type: typeForCheck });
357
+ const rules = pluralRules.safePluralRules(locale, { type: typeForCheck });
357
358
  rules.resolvedOptions().pluralCategories.forEach(c => allPluralCategoriesCheck.add(c));
358
359
  }
359
360
  catch {
360
- new Intl.PluralRules('en', { type: typeForCheck }).resolvedOptions().pluralCategories.forEach(c => allPluralCategoriesCheck.add(c));
361
+ pluralRules.safePluralRules('en', { type: typeForCheck }).resolvedOptions().pluralCategories.forEach(c => allPluralCategoriesCheck.add(c));
361
362
  }
362
363
  }
363
364
  const pluralCategoriesCheck = Array.from(allPluralCategoriesCheck).sort();
@@ -551,12 +552,12 @@ class CallExpressionHandler {
551
552
  const locales = this.config.locales || ['en'];
552
553
  for (const locale of locales) {
553
554
  try {
554
- const pluralRules = new Intl.PluralRules(locale, { type });
555
- const categories = pluralRules.resolvedOptions().pluralCategories;
555
+ const pluralRules$1 = pluralRules.safePluralRules(locale, { type });
556
+ const categories = pluralRules$1.resolvedOptions().pluralCategories;
556
557
  categories.forEach(cat => allPluralCategories.add(cat));
557
558
  }
558
559
  catch (e) {
559
- const englishRules = new Intl.PluralRules('en', { type });
560
+ const englishRules = pluralRules.safePluralRules('en', { type });
560
561
  const categories = englishRules.resolvedOptions().pluralCategories;
561
562
  categories.forEach(cat => allPluralCategories.add(cat));
562
563
  }
@@ -567,7 +568,7 @@ class CallExpressionHandler {
567
568
  const primaryLang = this.config.extract?.primaryLanguage || (Array.isArray(this.config.locales) ? this.config.locales[0] : undefined) || 'en';
568
569
  let primaryIsSingleOther = false;
569
570
  try {
570
- const primaryCats = new Intl.PluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
571
+ const primaryCats = pluralRules.safePluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
571
572
  if (primaryCats.length === 1 && primaryCats[0] === 'other')
572
573
  primaryIsSingleOther = true;
573
574
  }
@@ -710,13 +711,13 @@ class CallExpressionHandler {
710
711
  const allPluralCategories = new Set();
711
712
  for (const locale of this.config.locales) {
712
713
  try {
713
- const pluralRules = new Intl.PluralRules(locale, { type });
714
- const categories = pluralRules.resolvedOptions().pluralCategories;
714
+ const pluralRules$1 = pluralRules.safePluralRules(locale, { type });
715
+ const categories = pluralRules$1.resolvedOptions().pluralCategories;
715
716
  categories.forEach(cat => allPluralCategories.add(cat));
716
717
  }
717
718
  catch (e) {
718
719
  // If a locale is invalid, fall back to English rules
719
- const englishRules = new Intl.PluralRules('en', { type });
720
+ const englishRules = pluralRules.safePluralRules('en', { type });
720
721
  const categories = englishRules.resolvedOptions().pluralCategories;
721
722
  categories.forEach(cat => allPluralCategories.add(cat));
722
723
  }
@@ -783,7 +784,7 @@ class CallExpressionHandler {
783
784
  const primaryLang = this.config.extract?.primaryLanguage || (Array.isArray(this.config.locales) ? this.config.locales[0] : undefined) || 'en';
784
785
  let primaryIsSingleOther = false;
785
786
  try {
786
- const primaryCats = new Intl.PluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
787
+ const primaryCats = pluralRules.safePluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
787
788
  if (primaryCats.length === 1 && primaryCats[0] === 'other')
788
789
  primaryIsSingleOther = true;
789
790
  }
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var pluralRules = require('../../utils/plural-rules.js');
4
+
3
5
  // Checks if a string looks like natural language (contains spaces, punctuation, etc.)
4
6
  const naturalLanguageChars = /[ ,?!;]/;
5
7
  const looksLikeNaturalLanguage = (s) => naturalLanguageChars.test(s);
@@ -170,13 +172,13 @@ function generatePluralKeys(key, defaultValue, ns, pluginContext, config, isOrdi
170
172
  const allPluralCategories = new Set();
171
173
  for (const locale of config.locales) {
172
174
  try {
173
- const pluralRules = new Intl.PluralRules(locale, { type });
174
- const categories = pluralRules.resolvedOptions().pluralCategories;
175
+ const pluralRules$1 = pluralRules.safePluralRules(locale, { type });
176
+ const categories = pluralRules$1.resolvedOptions().pluralCategories;
175
177
  categories.forEach(cat => allPluralCategories.add(cat));
176
178
  }
177
179
  catch (e) {
178
180
  // If a locale is invalid, fall back to English rules
179
- const englishRules = new Intl.PluralRules('en', { type });
181
+ const englishRules = pluralRules.safePluralRules('en', { type });
180
182
  const categories = englishRules.resolvedOptions().pluralCategories;
181
183
  categories.forEach(cat => allPluralCategories.add(cat));
182
184
  }
@@ -223,13 +225,13 @@ function generateContextPluralKeys(key, defaultValue, ns, context, pluginContext
223
225
  const allPluralCategories = new Set();
224
226
  for (const locale of config.locales) {
225
227
  try {
226
- const pluralRules = new Intl.PluralRules(locale, { type });
227
- const categories = pluralRules.resolvedOptions().pluralCategories;
228
+ const pluralRules$1 = pluralRules.safePluralRules(locale, { type });
229
+ const categories = pluralRules$1.resolvedOptions().pluralCategories;
228
230
  categories.forEach(cat => allPluralCategories.add(cat));
229
231
  }
230
232
  catch (e) {
231
233
  // If a locale is invalid, fall back to English rules
232
- const englishRules = new Intl.PluralRules(config.extract.primaryLanguage || 'en', { type });
234
+ const englishRules = pluralRules.safePluralRules(config.extract.primaryLanguage || 'en', { type });
233
235
  const categories = englishRules.resolvedOptions().pluralCategories;
234
236
  categories.forEach(cat => allPluralCategories.add(cat));
235
237
  }
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var pluralRules = require('../../utils/plural-rules.js');
3
4
  var jsxParser = require('./jsx-parser.js');
4
5
  var astUtils = require('./ast-utils.js');
5
6
 
@@ -360,13 +361,13 @@ class JSXHandler {
360
361
  const allPluralCategories = new Set();
361
362
  for (const locale of this.config.locales) {
362
363
  try {
363
- const pluralRules = new Intl.PluralRules(locale, { type });
364
- const categories = pluralRules.resolvedOptions().pluralCategories;
364
+ const pluralRules$1 = pluralRules.safePluralRules(locale, { type });
365
+ const categories = pluralRules$1.resolvedOptions().pluralCategories;
365
366
  categories.forEach(cat => allPluralCategories.add(cat));
366
367
  }
367
368
  catch (e) {
368
369
  // If a locale is invalid, fall back to English rules
369
- const englishRules = new Intl.PluralRules('en', { type });
370
+ const englishRules = pluralRules.safePluralRules('en', { type });
370
371
  const categories = englishRules.resolvedOptions().pluralCategories;
371
372
  categories.forEach(cat => allPluralCategories.add(cat));
372
373
  }
@@ -9,6 +9,7 @@ var keyFinder = require('./extractor/core/key-finder.js');
9
9
  require('glob');
10
10
  var nestedObject = require('./utils/nested-object.js');
11
11
  var fileUtils = require('./utils/file-utils.js');
12
+ var pluralRules = require('./utils/plural-rules.js');
12
13
  var funnelMsgTracker = require('./utils/funnel-msg-tracker.js');
13
14
  require('./extractor/parsers/jsx-parser.js');
14
15
 
@@ -142,12 +143,12 @@ async function generateStatusReport(config) {
142
143
  const getLocalePluralCategories = (locale, isOrdinal) => {
143
144
  try {
144
145
  const type = isOrdinal ? 'ordinal' : 'cardinal';
145
- const pluralRules = new Intl.PluralRules(locale, { type });
146
- return pluralRules.resolvedOptions().pluralCategories;
146
+ const pluralRules$1 = pluralRules.safePluralRules(locale, { type });
147
+ return pluralRules$1.resolvedOptions().pluralCategories;
147
148
  }
148
149
  catch (e) {
149
150
  // Fallback to English if locale is invalid
150
- const fallbackRules = new Intl.PluralRules('en', { type: isOrdinal ? 'ordinal' : 'cardinal' });
151
+ const fallbackRules = pluralRules.safePluralRules('en', { type: isOrdinal ? 'ordinal' : 'cardinal' });
151
152
  return fallbackRules.resolvedOptions().pluralCategories;
152
153
  }
153
154
  };
@@ -10,6 +10,7 @@ var defaultValue = require('./utils/default-value.js');
10
10
  var fileUtils = require('./utils/file-utils.js');
11
11
  var funnelMsgTracker = require('./utils/funnel-msg-tracker.js');
12
12
  var nestedObject = require('./utils/nested-object.js');
13
+ var pluralRules = require('./utils/plural-rules.js');
13
14
 
14
15
  /**
15
16
  * Synchronizes translation files across different locales by ensuring all secondary
@@ -92,7 +93,7 @@ async function runSyncer(config, options = {}) {
92
93
  const sep = config.extract.pluralSeparator ?? '_';
93
94
  const localeCardinalCategories = (() => {
94
95
  try {
95
- return new Set(new Intl.PluralRules(lang, { type: 'cardinal' }).resolvedOptions().pluralCategories);
96
+ return new Set(pluralRules.safePluralRules(lang, { type: 'cardinal' }).resolvedOptions().pluralCategories);
96
97
  }
97
98
  catch {
98
99
  return new Set(['one', 'other']);
@@ -100,7 +101,7 @@ async function runSyncer(config, options = {}) {
100
101
  })();
101
102
  const localeOrdinalCategories = (() => {
102
103
  try {
103
- return new Set(new Intl.PluralRules(lang, { type: 'ordinal' }).resolvedOptions().pluralCategories);
104
+ return new Set(pluralRules.safePluralRules(lang, { type: 'ordinal' }).resolvedOptions().pluralCategories);
104
105
  }
105
106
  catch {
106
107
  return new Set(['one', 'other', 'two', 'few']);
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Creates an Intl.PluralRules instance, falling back to English ('en')
5
+ * if the given locale is not a valid BCP 47 language tag.
6
+ *
7
+ * This allows projects to use custom locale codes (e.g. 'E', 'F')
8
+ * that are not recognized by the Intl API.
9
+ */
10
+ function safePluralRules(locale, options) {
11
+ try {
12
+ return new Intl.PluralRules(locale, options);
13
+ }
14
+ catch {
15
+ return new Intl.PluralRules('en', options);
16
+ }
17
+ }
18
+
19
+ exports.safePluralRules = safePluralRules;
package/dist/esm/cli.js CHANGED
@@ -29,7 +29,7 @@ const program = new Command();
29
29
  program
30
30
  .name('i18next-cli')
31
31
  .description('A unified, high-performance i18next CLI.')
32
- .version('1.50.6'); // This string is replaced with the actual version at build time by rollup
32
+ .version('1.50.8'); // This string is replaced with the actual version at build time by rollup
33
33
  // new: global config override option
34
34
  program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
35
35
  program
@@ -4,6 +4,7 @@ import { getNestedKeys, getNestedValue, setNestedValue } from '../../utils/neste
4
4
  import { getOutputPath, loadTranslationFile } from '../../utils/file-utils.js';
5
5
  import { resolveDefaultValue } from '../../utils/default-value.js';
6
6
  import { ConsoleLogger } from '../../utils/logger.js';
7
+ import { safePluralRules } from '../../utils/plural-rules.js';
7
8
 
8
9
  // used for natural language check
9
10
  const chars = [' ', ',', '?', '!', ';'];
@@ -262,25 +263,14 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
262
263
  }
263
264
  }
264
265
  // Get the plural categories for the target language (only used for filtering extracted keys)
266
+ // safePluralRules falls back to 'en' for non-BCP47 custom locale codes (e.g. 'E', 'F')
265
267
  const targetLanguagePluralCategories = new Set();
268
+ const cardinalRules = safePluralRules(locale, { type: 'cardinal' });
269
+ const ordinalRules = safePluralRules(locale, { type: 'ordinal' });
266
270
  // Track cardinal plural categories separately so we can special-case single-"other" languages
267
- let cardinalCategories = [];
268
- try {
269
- const cardinalRules = new Intl.PluralRules(locale, { type: 'cardinal' });
270
- const ordinalRules = new Intl.PluralRules(locale, { type: 'ordinal' });
271
- cardinalCategories = cardinalRules.resolvedOptions().pluralCategories;
272
- cardinalCategories.forEach(cat => targetLanguagePluralCategories.add(cat));
273
- ordinalRules.resolvedOptions().pluralCategories.forEach(cat => targetLanguagePluralCategories.add(`ordinal_${cat}`));
274
- }
275
- catch (e) {
276
- // Fallback to primaryLanguage (or English) if locale is invalid
277
- const fallbackLang = primaryLanguage || 'en';
278
- const cardinalRules = new Intl.PluralRules(fallbackLang, { type: 'cardinal' });
279
- const ordinalRules = new Intl.PluralRules(fallbackLang, { type: 'ordinal' });
280
- cardinalCategories = cardinalRules.resolvedOptions().pluralCategories;
281
- cardinalCategories.forEach(cat => targetLanguagePluralCategories.add(cat));
282
- ordinalRules.resolvedOptions().pluralCategories.forEach(cat => targetLanguagePluralCategories.add(`ordinal_${cat}`));
283
- }
271
+ const cardinalCategories = cardinalRules.resolvedOptions().pluralCategories;
272
+ cardinalCategories.forEach(cat => targetLanguagePluralCategories.add(cat));
273
+ ordinalRules.resolvedOptions().pluralCategories.forEach(cat => targetLanguagePluralCategories.add(`ordinal_${cat}`));
284
274
  // Prepare namespace pattern checking helpers
285
275
  const rawPreserve = config.extract.preservePatterns || [];
286
276
  // Helper to check if a key should be filtered out during extraction
@@ -834,7 +824,7 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
834
824
  const keysByNS = new Map();
835
825
  for (const k of keys.values()) {
836
826
  const ns = k.ns;
837
- const nsKey = (k.nsIsImplicit && (config.extract.defaultNS === false || config.extract.nsSeparator === false))
827
+ const nsKey = (k.nsIsImplicit && config.extract.defaultNS === false)
838
828
  ? NO_NS_TOKEN
839
829
  : String(ns ?? (config.extract.defaultNS ?? 'translation'));
840
830
  if (!keysByNS.has(nsKey))
@@ -885,9 +875,14 @@ async function getTranslations(keys, objectKeys, config, { syncPrimaryWithDefaul
885
875
  for (const ns of ignoreNamespaces) {
886
876
  namespacesToProcess.delete(ns);
887
877
  }
878
+ // When nsSeparator is false, keys resolved to the defaultNS (e.g. from
879
+ // useTranslation() with no args) should be treated as top-level, not
880
+ // wrapped under the namespace name.
881
+ const defaultNs = String(config.extract.defaultNS ?? 'translation');
882
+ const isTopLevel = (nsKey) => nsKey === NO_NS_TOKEN || (config.extract.nsSeparator === false && nsKey === defaultNs);
888
883
  for (const nsKey of namespacesToProcess) {
889
884
  const nsKeys = keysByNS.get(nsKey) || [];
890
- if (nsKey === NO_NS_TOKEN) {
885
+ if (isTopLevel(nsKey)) {
891
886
  // keys without namespace -> merged into top-level of the merged file
892
887
  const built = buildNewTranslationsForNs(nsKeys, existingMergedFile, config, locale, undefined, preservePatterns, objectKeys, syncPrimaryWithDefaults, undefined, logger);
893
888
  Object.assign(newMergedTranslations, built);
@@ -1,3 +1,4 @@
1
+ import { safePluralRules } from '../../utils/plural-rules.js';
1
2
  import { lineColumnFromOffset, isSimpleTemplateLiteral, getObjectPropValue, getObjectPropValueExpression } from './ast-utils.js';
2
3
 
3
4
  // Helper to escape regex characters
@@ -339,7 +340,7 @@ class CallExpressionHandler {
339
340
  const primaryLang = this.config.extract?.primaryLanguage || (Array.isArray(this.config.locales) ? this.config.locales[0] : undefined) || 'en';
340
341
  let isSingleOther = false;
341
342
  try {
342
- const primaryCategories = new Intl.PluralRules(primaryLang, { type: typeForCheck }).resolvedOptions().pluralCategories;
343
+ const primaryCategories = safePluralRules(primaryLang, { type: typeForCheck }).resolvedOptions().pluralCategories;
343
344
  if (primaryCategories.length === 1 && primaryCategories[0] === 'other') {
344
345
  isSingleOther = true;
345
346
  }
@@ -351,11 +352,11 @@ class CallExpressionHandler {
351
352
  const allPluralCategoriesCheck = new Set();
352
353
  for (const locale of this.config.locales) {
353
354
  try {
354
- const rules = new Intl.PluralRules(locale, { type: typeForCheck });
355
+ const rules = safePluralRules(locale, { type: typeForCheck });
355
356
  rules.resolvedOptions().pluralCategories.forEach(c => allPluralCategoriesCheck.add(c));
356
357
  }
357
358
  catch {
358
- new Intl.PluralRules('en', { type: typeForCheck }).resolvedOptions().pluralCategories.forEach(c => allPluralCategoriesCheck.add(c));
359
+ safePluralRules('en', { type: typeForCheck }).resolvedOptions().pluralCategories.forEach(c => allPluralCategoriesCheck.add(c));
359
360
  }
360
361
  }
361
362
  const pluralCategoriesCheck = Array.from(allPluralCategoriesCheck).sort();
@@ -549,12 +550,12 @@ class CallExpressionHandler {
549
550
  const locales = this.config.locales || ['en'];
550
551
  for (const locale of locales) {
551
552
  try {
552
- const pluralRules = new Intl.PluralRules(locale, { type });
553
+ const pluralRules = safePluralRules(locale, { type });
553
554
  const categories = pluralRules.resolvedOptions().pluralCategories;
554
555
  categories.forEach(cat => allPluralCategories.add(cat));
555
556
  }
556
557
  catch (e) {
557
- const englishRules = new Intl.PluralRules('en', { type });
558
+ const englishRules = safePluralRules('en', { type });
558
559
  const categories = englishRules.resolvedOptions().pluralCategories;
559
560
  categories.forEach(cat => allPluralCategories.add(cat));
560
561
  }
@@ -565,7 +566,7 @@ class CallExpressionHandler {
565
566
  const primaryLang = this.config.extract?.primaryLanguage || (Array.isArray(this.config.locales) ? this.config.locales[0] : undefined) || 'en';
566
567
  let primaryIsSingleOther = false;
567
568
  try {
568
- const primaryCats = new Intl.PluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
569
+ const primaryCats = safePluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
569
570
  if (primaryCats.length === 1 && primaryCats[0] === 'other')
570
571
  primaryIsSingleOther = true;
571
572
  }
@@ -708,13 +709,13 @@ class CallExpressionHandler {
708
709
  const allPluralCategories = new Set();
709
710
  for (const locale of this.config.locales) {
710
711
  try {
711
- const pluralRules = new Intl.PluralRules(locale, { type });
712
+ const pluralRules = safePluralRules(locale, { type });
712
713
  const categories = pluralRules.resolvedOptions().pluralCategories;
713
714
  categories.forEach(cat => allPluralCategories.add(cat));
714
715
  }
715
716
  catch (e) {
716
717
  // If a locale is invalid, fall back to English rules
717
- const englishRules = new Intl.PluralRules('en', { type });
718
+ const englishRules = safePluralRules('en', { type });
718
719
  const categories = englishRules.resolvedOptions().pluralCategories;
719
720
  categories.forEach(cat => allPluralCategories.add(cat));
720
721
  }
@@ -781,7 +782,7 @@ class CallExpressionHandler {
781
782
  const primaryLang = this.config.extract?.primaryLanguage || (Array.isArray(this.config.locales) ? this.config.locales[0] : undefined) || 'en';
782
783
  let primaryIsSingleOther = false;
783
784
  try {
784
- const primaryCats = new Intl.PluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
785
+ const primaryCats = safePluralRules(primaryLang, { type }).resolvedOptions().pluralCategories;
785
786
  if (primaryCats.length === 1 && primaryCats[0] === 'other')
786
787
  primaryIsSingleOther = true;
787
788
  }
@@ -1,3 +1,5 @@
1
+ import { safePluralRules } from '../../utils/plural-rules.js';
2
+
1
3
  // Checks if a string looks like natural language (contains spaces, punctuation, etc.)
2
4
  const naturalLanguageChars = /[ ,?!;]/;
3
5
  const looksLikeNaturalLanguage = (s) => naturalLanguageChars.test(s);
@@ -168,13 +170,13 @@ function generatePluralKeys(key, defaultValue, ns, pluginContext, config, isOrdi
168
170
  const allPluralCategories = new Set();
169
171
  for (const locale of config.locales) {
170
172
  try {
171
- const pluralRules = new Intl.PluralRules(locale, { type });
173
+ const pluralRules = safePluralRules(locale, { type });
172
174
  const categories = pluralRules.resolvedOptions().pluralCategories;
173
175
  categories.forEach(cat => allPluralCategories.add(cat));
174
176
  }
175
177
  catch (e) {
176
178
  // If a locale is invalid, fall back to English rules
177
- const englishRules = new Intl.PluralRules('en', { type });
179
+ const englishRules = safePluralRules('en', { type });
178
180
  const categories = englishRules.resolvedOptions().pluralCategories;
179
181
  categories.forEach(cat => allPluralCategories.add(cat));
180
182
  }
@@ -221,13 +223,13 @@ function generateContextPluralKeys(key, defaultValue, ns, context, pluginContext
221
223
  const allPluralCategories = new Set();
222
224
  for (const locale of config.locales) {
223
225
  try {
224
- const pluralRules = new Intl.PluralRules(locale, { type });
226
+ const pluralRules = safePluralRules(locale, { type });
225
227
  const categories = pluralRules.resolvedOptions().pluralCategories;
226
228
  categories.forEach(cat => allPluralCategories.add(cat));
227
229
  }
228
230
  catch (e) {
229
231
  // If a locale is invalid, fall back to English rules
230
- const englishRules = new Intl.PluralRules(config.extract.primaryLanguage || 'en', { type });
232
+ const englishRules = safePluralRules(config.extract.primaryLanguage || 'en', { type });
231
233
  const categories = englishRules.resolvedOptions().pluralCategories;
232
234
  categories.forEach(cat => allPluralCategories.add(cat));
233
235
  }
@@ -1,3 +1,4 @@
1
+ import { safePluralRules } from '../../utils/plural-rules.js';
1
2
  import { extractFromTransComponent } from './jsx-parser.js';
2
3
  import { lineColumnFromOffset, getObjectPropValue } from './ast-utils.js';
3
4
 
@@ -358,13 +359,13 @@ class JSXHandler {
358
359
  const allPluralCategories = new Set();
359
360
  for (const locale of this.config.locales) {
360
361
  try {
361
- const pluralRules = new Intl.PluralRules(locale, { type });
362
+ const pluralRules = safePluralRules(locale, { type });
362
363
  const categories = pluralRules.resolvedOptions().pluralCategories;
363
364
  categories.forEach(cat => allPluralCategories.add(cat));
364
365
  }
365
366
  catch (e) {
366
367
  // If a locale is invalid, fall back to English rules
367
- const englishRules = new Intl.PluralRules('en', { type });
368
+ const englishRules = safePluralRules('en', { type });
368
369
  const categories = englishRules.resolvedOptions().pluralCategories;
369
370
  categories.forEach(cat => allPluralCategories.add(cat));
370
371
  }
@@ -7,6 +7,7 @@ import { findKeys } from './extractor/core/key-finder.js';
7
7
  import 'glob';
8
8
  import { getNestedValue } from './utils/nested-object.js';
9
9
  import { loadTranslationFile, getOutputPath } from './utils/file-utils.js';
10
+ import { safePluralRules } from './utils/plural-rules.js';
10
11
  import { shouldShowFunnel, recordFunnelShown } from './utils/funnel-msg-tracker.js';
11
12
  import './extractor/parsers/jsx-parser.js';
12
13
 
@@ -140,12 +141,12 @@ async function generateStatusReport(config) {
140
141
  const getLocalePluralCategories = (locale, isOrdinal) => {
141
142
  try {
142
143
  const type = isOrdinal ? 'ordinal' : 'cardinal';
143
- const pluralRules = new Intl.PluralRules(locale, { type });
144
+ const pluralRules = safePluralRules(locale, { type });
144
145
  return pluralRules.resolvedOptions().pluralCategories;
145
146
  }
146
147
  catch (e) {
147
148
  // Fallback to English if locale is invalid
148
- const fallbackRules = new Intl.PluralRules('en', { type: isOrdinal ? 'ordinal' : 'cardinal' });
149
+ const fallbackRules = safePluralRules('en', { type: isOrdinal ? 'ordinal' : 'cardinal' });
149
150
  return fallbackRules.resolvedOptions().pluralCategories;
150
151
  }
151
152
  };
@@ -8,6 +8,7 @@ import { resolveDefaultValue } from './utils/default-value.js';
8
8
  import { getOutputPath, loadTranslationFile, inferFormatFromPath, loadRawJson5Content, serializeTranslationFile } from './utils/file-utils.js';
9
9
  import { shouldShowFunnel, recordFunnelShown } from './utils/funnel-msg-tracker.js';
10
10
  import { getNestedKeys, getNestedValue, setNestedValue } from './utils/nested-object.js';
11
+ import { safePluralRules } from './utils/plural-rules.js';
11
12
 
12
13
  /**
13
14
  * Synchronizes translation files across different locales by ensuring all secondary
@@ -90,7 +91,7 @@ async function runSyncer(config, options = {}) {
90
91
  const sep = config.extract.pluralSeparator ?? '_';
91
92
  const localeCardinalCategories = (() => {
92
93
  try {
93
- return new Set(new Intl.PluralRules(lang, { type: 'cardinal' }).resolvedOptions().pluralCategories);
94
+ return new Set(safePluralRules(lang, { type: 'cardinal' }).resolvedOptions().pluralCategories);
94
95
  }
95
96
  catch {
96
97
  return new Set(['one', 'other']);
@@ -98,7 +99,7 @@ async function runSyncer(config, options = {}) {
98
99
  })();
99
100
  const localeOrdinalCategories = (() => {
100
101
  try {
101
- return new Set(new Intl.PluralRules(lang, { type: 'ordinal' }).resolvedOptions().pluralCategories);
102
+ return new Set(safePluralRules(lang, { type: 'ordinal' }).resolvedOptions().pluralCategories);
102
103
  }
103
104
  catch {
104
105
  return new Set(['one', 'other', 'two', 'few']);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Creates an Intl.PluralRules instance, falling back to English ('en')
3
+ * if the given locale is not a valid BCP 47 language tag.
4
+ *
5
+ * This allows projects to use custom locale codes (e.g. 'E', 'F')
6
+ * that are not recognized by the Intl API.
7
+ */
8
+ function safePluralRules(locale, options) {
9
+ try {
10
+ return new Intl.PluralRules(locale, options);
11
+ }
12
+ catch {
13
+ return new Intl.PluralRules('en', options);
14
+ }
15
+ }
16
+
17
+ export { safePluralRules };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18next-cli",
3
- "version": "1.50.6",
3
+ "version": "1.50.8",
4
4
  "description": "A unified, high-performance i18next CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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,EAAE,MAAM,gBAAgB,CAAA;AAk5B9F;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,CA6I9B"}
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,gBAAgB,CAAA;AAu4B9F;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,CAoJ9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"call-expression-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/call-expression-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAgB,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1G,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAW7D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,kBAAkB,CAAoB;IACvC,UAAU,cAAoB;IACrC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAAsC;gBAG7D,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM,EAC5B,iBAAiB,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAA2B;IAW3E;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,CAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI;IAyYxG;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,oBAAoB;IAkF5B,OAAO,CAAC,wBAAwB;IAyEhC;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IA8BpC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,sBAAsB;IA2C9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IAyMxB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
1
+ {"version":3,"file":"call-expression-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/call-expression-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAgB,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1G,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAY7D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,kBAAkB,CAAoB;IACvC,UAAU,cAAoB;IACrC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAAsC;gBAG7D,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM,EAC5B,iBAAiB,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAA2B;IAW3E;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,CAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI;IAyYxG;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,oBAAoB;IAkF5B,OAAO,CAAC,wBAAwB;IAyEhC;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IA8BpC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,sBAAsB;IA2C9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IAyMxB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"comment-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/comment-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAMzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC1F,IAAI,CAqJN"}
1
+ {"version":3,"file":"comment-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/comment-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAOzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC1F,IAAI,CAqJN"}
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,WAAW,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAgB,MAAM,gBAAgB,CAAA;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAQ7D,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;gBAGlC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM;IAS9B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;;;;;;;OAQG;IACH,gBAAgB,CAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IAyUjI;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,0BAA0B;IAkIlC;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;CAevB"}
1
+ {"version":3,"file":"jsx-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,WAAW,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAgB,MAAM,gBAAgB,CAAA;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAS7D,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;gBAGlC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM;IAS9B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;;;;;;;OAQG;IACH,gBAAgB,CAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IAyUjI;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,0BAA0B;IAkIlC;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;CAevB"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,YAAY,CAAA;AAIpE;;GAEG;AACH,UAAU,aAAa;IACrB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAqDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAE,aAAkB,iBAuBzF"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,YAAY,CAAA;AAKpE;;GAEG;AACH,UAAU,aAAa;IACrB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAqDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAE,aAAkB,iBAuBzF"}
@@ -1 +1 @@
1
- {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../src/syncer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAM9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,iBA+LnD"}
1
+ {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../src/syncer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAO9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,iBA+LnD"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Creates an Intl.PluralRules instance, falling back to English ('en')
3
+ * if the given locale is not a valid BCP 47 language tag.
4
+ *
5
+ * This allows projects to use custom locale codes (e.g. 'E', 'F')
6
+ * that are not recognized by the Intl API.
7
+ */
8
+ export declare function safePluralRules(locale: string, options?: Intl.PluralRulesOptions): Intl.PluralRules;
9
+ //# sourceMappingURL=plural-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plural-rules.d.ts","sourceRoot":"","sources":["../../src/utils/plural-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAMpG"}