i18next 25.10.9 → 26.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2025 i18next
3
+ Copyright (c) 2011-present i18next
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -14,7 +14,7 @@ const defer = () => {
14
14
  };
15
15
  const makeString = object => {
16
16
  if (object == null) return '';
17
- return '' + object;
17
+ return String(object);
18
18
  };
19
19
  const copy = (a, s, t) => {
20
20
  a.forEach(m => {
@@ -22,7 +22,7 @@ const copy = (a, s, t) => {
22
22
  });
23
23
  };
24
24
  const lastOfPathSeparatorRegExp = /###/g;
25
- const cleanKey = key => key && key.indexOf('###') > -1 ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
25
+ const cleanKey = key => key && key.includes('###') ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
26
26
  const canNotTraverseDeeper = object => !object || isString(object);
27
27
  const getLastOfPath = (object, path, Empty) => {
28
28
  const stack = !isString(path) ? path : path.split('.');
@@ -107,7 +107,7 @@ const deepExtend = (target, source, overwrite) => {
107
107
  return target;
108
108
  };
109
109
  const regexEscape = str => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
110
- var _entityMap = {
110
+ const _entityMap = {
111
111
  '&': '&',
112
112
  '<': '&lt;',
113
113
  '>': '&gt;',
@@ -146,7 +146,7 @@ const looksLikeObjectPathRegExpCache = new RegExpCache(20);
146
146
  const looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
147
147
  nsSeparator = nsSeparator || '';
148
148
  keySeparator = keySeparator || '';
149
- const possibleChars = chars.filter(c => nsSeparator.indexOf(c) < 0 && keySeparator.indexOf(c) < 0);
149
+ const possibleChars = chars.filter(c => !nsSeparator.includes(c) && !keySeparator.includes(c));
150
150
  if (possibleChars.length === 0) return true;
151
151
  const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map(c => c === '?' ? '\\?' : c).join('|')})`);
152
152
  let matched = !r.test(key);
@@ -179,7 +179,7 @@ const deepFind = (obj, path, keySeparator = '.') => {
179
179
  nextPath += tokens[j];
180
180
  next = current[nextPath];
181
181
  if (next !== undefined) {
182
- if (['string', 'number', 'boolean'].indexOf(typeof next) > -1 && j < tokens.length - 1) {
182
+ if (['string', 'number', 'boolean'].includes(typeof next) && j < tokens.length - 1) {
183
183
  continue;
184
184
  }
185
185
  i += j - i + 1;
@@ -270,6 +270,14 @@ class EventEmitter {
270
270
  }
271
271
  this.observers[event].delete(listener);
272
272
  }
273
+ once(event, listener) {
274
+ const wrapper = (...args) => {
275
+ listener(...args);
276
+ this.off(event, wrapper);
277
+ };
278
+ this.on(event, wrapper);
279
+ return this;
280
+ }
273
281
  emit(event, ...args) {
274
282
  if (this.observers[event]) {
275
283
  const cloned = Array.from(this.observers[event].entries());
@@ -283,7 +291,7 @@ class EventEmitter {
283
291
  const cloned = Array.from(this.observers['*'].entries());
284
292
  cloned.forEach(([observer, numTimesAdded]) => {
285
293
  for (let i = 0; i < numTimesAdded; i++) {
286
- observer.apply(observer, [event, ...args]);
294
+ observer(event, ...args);
287
295
  }
288
296
  });
289
297
  }
@@ -306,7 +314,7 @@ class ResourceStore extends EventEmitter {
306
314
  }
307
315
  }
308
316
  addNamespaces(ns) {
309
- if (this.options.ns.indexOf(ns) < 0) {
317
+ if (!this.options.ns.includes(ns)) {
310
318
  this.options.ns.push(ns);
311
319
  }
312
320
  }
@@ -320,7 +328,7 @@ class ResourceStore extends EventEmitter {
320
328
  const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
321
329
  const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
322
330
  let path;
323
- if (lng.indexOf('.') > -1) {
331
+ if (lng.includes('.')) {
324
332
  path = lng.split('.');
325
333
  } else {
326
334
  path = [lng, ns];
@@ -335,7 +343,7 @@ class ResourceStore extends EventEmitter {
335
343
  }
336
344
  }
337
345
  const result = getPath(this.data, path);
338
- if (!result && !ns && !key && lng.indexOf('.') > -1) {
346
+ if (!result && !ns && !key && lng.includes('.')) {
339
347
  lng = path[0];
340
348
  ns = path[1];
341
349
  key = path.slice(2).join('.');
@@ -349,7 +357,7 @@ class ResourceStore extends EventEmitter {
349
357
  const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
350
358
  let path = [lng, ns];
351
359
  if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
352
- if (lng.indexOf('.') > -1) {
360
+ if (lng.includes('.')) {
353
361
  path = lng.split('.');
354
362
  value = ns;
355
363
  ns = path[1];
@@ -373,7 +381,7 @@ class ResourceStore extends EventEmitter {
373
381
  skipCopy: false
374
382
  }) {
375
383
  let path = [lng, ns];
376
- if (lng.indexOf('.') > -1) {
384
+ if (lng.includes('.')) {
377
385
  path = lng.split('.');
378
386
  deep = resources;
379
387
  resources = ns;
@@ -463,7 +471,6 @@ function keysFromSelector(selector, opts) {
463
471
  return path.join(keySeparator);
464
472
  }
465
473
 
466
- const checkedLoadedFor = {};
467
474
  const shouldHandleAsObject = res => !isString(res) && typeof res !== 'boolean' && typeof res !== 'number';
468
475
  class Translator extends EventEmitter {
469
476
  constructor(services, options = {}) {
@@ -474,6 +481,7 @@ class Translator extends EventEmitter {
474
481
  this.options.keySeparator = '.';
475
482
  }
476
483
  this.logger = baseLogger.create('translator');
484
+ this.checkedLoadedFor = {};
477
485
  }
478
486
  changeLanguage(lng) {
479
487
  if (lng) this.language = lng;
@@ -498,7 +506,7 @@ class Translator extends EventEmitter {
498
506
  if (nsSeparator === undefined) nsSeparator = ':';
499
507
  const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
500
508
  let namespaces = opt.ns || this.options.defaultNS || [];
501
- const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1;
509
+ const wouldCheckForNsInKey = nsSeparator && key.includes(nsSeparator);
502
510
  const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !opt.keySeparator && !this.options.userDefinedNsSeparator && !opt.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
503
511
  if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
504
512
  const m = key.match(this.interpolator.nestingRegexp);
@@ -509,7 +517,7 @@ class Translator extends EventEmitter {
509
517
  };
510
518
  }
511
519
  const parts = key.split(nsSeparator);
512
- if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
520
+ if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.includes(parts[0])) namespaces = parts.shift();
513
521
  key = parts.join(keySeparator);
514
522
  }
515
523
  return {
@@ -596,7 +604,7 @@ class Translator extends EventEmitter {
596
604
  }
597
605
  const handleAsObject = shouldHandleAsObject(resForObjHndl);
598
606
  const resType = Object.prototype.toString.apply(resForObjHndl);
599
- if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
607
+ if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && !noObject.includes(resType) && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
600
608
  if (!opt.returnObjects && !this.options.returnObjects) {
601
609
  if (!this.options.returnedObjectHandler) {
602
610
  this.logger.warn('accessing an object - but returnObjects options is not enabled!');
@@ -692,7 +700,7 @@ class Translator extends EventEmitter {
692
700
  if (this.options.saveMissingPlurals && needsPluralHandling) {
693
701
  lngs.forEach(language => {
694
702
  const suffixes = this.pluralResolver.getSuffixes(language, opt);
695
- if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) {
703
+ if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && !suffixes.includes(`${this.options.pluralSeparator}zero`)) {
696
704
  suffixes.push(`${this.options.pluralSeparator}zero`);
697
705
  }
698
706
  suffixes.forEach(suffix => {
@@ -802,8 +810,8 @@ class Translator extends EventEmitter {
802
810
  namespaces.forEach(ns => {
803
811
  if (this.isValidLookup(found)) return;
804
812
  usedNS = ns;
805
- if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
806
- checkedLoadedFor[`${codes[0]}-${ns}`] = true;
813
+ if (!this.checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
814
+ this.checkedLoadedFor[`${codes[0]}-${ns}`] = true;
807
815
  this.logger.warn(`key "${usedKey}" for languages "${codes.join(', ')}" won't get resolved as namespace "${usedNS}" was not yet loaded`, 'This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!');
808
816
  }
809
817
  codes.forEach(code => {
@@ -818,7 +826,7 @@ class Translator extends EventEmitter {
818
826
  const zeroSuffix = `${this.options.pluralSeparator}zero`;
819
827
  const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
820
828
  if (needsPluralHandling) {
821
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
829
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
822
830
  finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
823
831
  }
824
832
  finalKeys.push(key + pluralSuffix);
@@ -830,7 +838,7 @@ class Translator extends EventEmitter {
830
838
  const contextKey = `${key}${this.options.contextSeparator || '_'}${opt.context}`;
831
839
  finalKeys.push(contextKey);
832
840
  if (needsPluralHandling) {
833
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
841
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
834
842
  finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
835
843
  }
836
844
  finalKeys.push(contextKey + pluralSuffix);
@@ -891,7 +899,7 @@ class Translator extends EventEmitter {
891
899
  static hasDefaultValue(options) {
892
900
  const prefix = 'defaultValue';
893
901
  for (const option in options) {
894
- if (Object.prototype.hasOwnProperty.call(options, option) && prefix === option.substring(0, prefix.length) && undefined !== options[option]) {
902
+ if (Object.prototype.hasOwnProperty.call(options, option) && option.startsWith(prefix) && undefined !== options[option]) {
895
903
  return true;
896
904
  }
897
905
  }
@@ -907,7 +915,7 @@ class LanguageUtil {
907
915
  }
908
916
  getScriptPartFromCode(code) {
909
917
  code = getCleanedCode(code);
910
- if (!code || code.indexOf('-') < 0) return null;
918
+ if (!code || !code.includes('-')) return null;
911
919
  const p = code.split('-');
912
920
  if (p.length === 2) return null;
913
921
  p.pop();
@@ -916,12 +924,12 @@ class LanguageUtil {
916
924
  }
917
925
  getLanguagePartFromCode(code) {
918
926
  code = getCleanedCode(code);
919
- if (!code || code.indexOf('-') < 0) return code;
927
+ if (!code || !code.includes('-')) return code;
920
928
  const p = code.split('-');
921
929
  return this.formatLanguageCode(p[0]);
922
930
  }
923
931
  formatLanguageCode(code) {
924
- if (isString(code) && code.indexOf('-') > -1) {
932
+ if (isString(code) && code.includes('-')) {
925
933
  let formattedCode;
926
934
  try {
927
935
  formattedCode = Intl.getCanonicalLocales(code)[0];
@@ -941,7 +949,7 @@ class LanguageUtil {
941
949
  if (this.options.load === 'languageOnly' || this.options.nonExplicitSupportedLngs) {
942
950
  code = this.getLanguagePartFromCode(code);
943
951
  }
944
- return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1;
952
+ return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.includes(code);
945
953
  }
946
954
  getBestMatchFromCodes(codes) {
947
955
  if (!codes) return null;
@@ -959,10 +967,11 @@ class LanguageUtil {
959
967
  const lngOnly = this.getLanguagePartFromCode(code);
960
968
  if (this.isSupportedCode(lngOnly)) return found = lngOnly;
961
969
  found = this.options.supportedLngs.find(supportedLng => {
962
- if (supportedLng === lngOnly) return supportedLng;
963
- if (supportedLng.indexOf('-') < 0 && lngOnly.indexOf('-') < 0) return;
964
- if (supportedLng.indexOf('-') > 0 && lngOnly.indexOf('-') < 0 && supportedLng.substring(0, supportedLng.indexOf('-')) === lngOnly) return supportedLng;
965
- if (supportedLng.indexOf(lngOnly) === 0 && lngOnly.length > 1) return supportedLng;
970
+ if (supportedLng === lngOnly) return true;
971
+ if (!supportedLng.includes('-') && !lngOnly.includes('-')) return false;
972
+ if (supportedLng.includes('-') && !lngOnly.includes('-') && supportedLng.slice(0, supportedLng.indexOf('-')) === lngOnly) return true;
973
+ if (supportedLng.startsWith(lngOnly) && lngOnly.length > 1) return true;
974
+ return false;
966
975
  });
967
976
  });
968
977
  }
@@ -993,7 +1002,7 @@ class LanguageUtil {
993
1002
  this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
994
1003
  }
995
1004
  };
996
- if (isString(code) && (code.indexOf('-') > -1 || code.indexOf('_') > -1)) {
1005
+ if (isString(code) && (code.includes('-') || code.includes('_'))) {
997
1006
  if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code));
998
1007
  if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code));
999
1008
  if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code));
@@ -1001,7 +1010,7 @@ class LanguageUtil {
1001
1010
  addCode(this.formatLanguageCode(code));
1002
1011
  }
1003
1012
  fallbackCodes.forEach(fc => {
1004
- if (codes.indexOf(fc) < 0) addCode(this.formatLanguageCode(fc));
1013
+ if (!codes.includes(fc)) addCode(this.formatLanguageCode(fc));
1005
1014
  });
1006
1015
  return codes;
1007
1016
  }
@@ -1157,7 +1166,7 @@ class Interpolator {
1157
1166
  let replaces;
1158
1167
  const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
1159
1168
  const handleFormat = key => {
1160
- if (key.indexOf(this.formatSeparator) < 0) {
1169
+ if (!key.includes(this.formatSeparator)) {
1161
1170
  const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
1162
1171
  return this.alwaysFormat ? this.format(path, undefined, lng, {
1163
1172
  ...options,
@@ -1227,7 +1236,7 @@ class Interpolator {
1227
1236
  let clonedOptions;
1228
1237
  const handleHasOptions = (key, inheritedOptions) => {
1229
1238
  const sep = this.nestingOptionsSeparator;
1230
- if (key.indexOf(sep) < 0) return key;
1239
+ if (!key.includes(sep)) return key;
1231
1240
  const c = key.split(new RegExp(`${regexEscape(sep)}[ ]*{`));
1232
1241
  let optionsString = `{${c[1]}`;
1233
1242
  key = c[0];
@@ -1247,7 +1256,7 @@ class Interpolator {
1247
1256
  this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
1248
1257
  return `${key}${sep}${optionsString}`;
1249
1258
  }
1250
- if (clonedOptions.defaultValue && clonedOptions.defaultValue.indexOf(this.prefix) > -1) delete clonedOptions.defaultValue;
1259
+ if (clonedOptions.defaultValue && clonedOptions.defaultValue.includes(this.prefix)) delete clonedOptions.defaultValue;
1251
1260
  return key;
1252
1261
  };
1253
1262
  while (match = this.nestingRegexp.exec(str)) {
@@ -1286,13 +1295,13 @@ class Interpolator {
1286
1295
  const parseFormatStr = formatStr => {
1287
1296
  let formatName = formatStr.toLowerCase().trim();
1288
1297
  const formatOptions = {};
1289
- if (formatStr.indexOf('(') > -1) {
1298
+ if (formatStr.includes('(')) {
1290
1299
  const p = formatStr.split('(');
1291
1300
  formatName = p[0].toLowerCase().trim();
1292
- const optStr = p[1].substring(0, p[1].length - 1);
1293
- if (formatName === 'currency' && optStr.indexOf(':') < 0) {
1301
+ const optStr = p[1].slice(0, -1);
1302
+ if (formatName === 'currency' && !optStr.includes(':')) {
1294
1303
  if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1295
- } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
1304
+ } else if (formatName === 'relativetime' && !optStr.includes(':')) {
1296
1305
  if (!formatOptions.range) formatOptions.range = optStr.trim();
1297
1306
  } else {
1298
1307
  const opts = optStr.split(';');
@@ -1387,8 +1396,8 @@ class Formatter {
1387
1396
  }
1388
1397
  format(value, format, lng, options = {}) {
1389
1398
  const formats = format.split(this.formatSeparator);
1390
- if (formats.length > 1 && formats[0].indexOf('(') > 1 && formats[0].indexOf(')') < 0 && formats.find(f => f.indexOf(')') > -1)) {
1391
- const lastIndex = formats.findIndex(f => f.indexOf(')') > -1);
1399
+ if (formats.length > 1 && formats[0].indexOf('(') > 1 && !formats[0].includes(')') && formats.find(f => f.includes(')'))) {
1400
+ const lastIndex = formats.findIndex(f => f.includes(')'));
1392
1401
  formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
1393
1402
  }
1394
1403
  const result = formats.reduce((mem, f) => {
@@ -1542,7 +1551,7 @@ class Connector extends EventEmitter {
1542
1551
  }
1543
1552
  if (err && data && tried < this.maxRetries) {
1544
1553
  setTimeout(() => {
1545
- this.read.call(this, lng, ns, fcName, tried + 1, wait * 2, callback);
1554
+ this.read(lng, ns, fcName, tried + 1, wait * 2, callback);
1546
1555
  }, wait);
1547
1556
  return;
1548
1557
  }
@@ -1646,7 +1655,6 @@ const get = () => ({
1646
1655
  nonExplicitSupportedLngs: false,
1647
1656
  load: 'all',
1648
1657
  preload: false,
1649
- simplifyPluralSuffix: true,
1650
1658
  keySeparator: '.',
1651
1659
  nsSeparator: ':',
1652
1660
  pluralSeparator: '_',
@@ -1683,7 +1691,6 @@ const get = () => ({
1683
1691
  },
1684
1692
  interpolation: {
1685
1693
  escapeValue: true,
1686
- format: value => value,
1687
1694
  prefix: '{{',
1688
1695
  suffix: '}}',
1689
1696
  formatSeparator: ',',
@@ -1700,10 +1707,9 @@ const transformOptions = options => {
1700
1707
  if (isString(options.ns)) options.ns = [options.ns];
1701
1708
  if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
1702
1709
  if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
1703
- if (options.supportedLngs?.indexOf?.('cimode') < 0) {
1710
+ if (options.supportedLngs && !options.supportedLngs.includes('cimode')) {
1704
1711
  options.supportedLngs = options.supportedLngs.concat(['cimode']);
1705
1712
  }
1706
- if (typeof options.initImmediate === 'boolean') options.initAsync = options.initImmediate;
1707
1713
  return options;
1708
1714
  };
1709
1715
 
@@ -1716,27 +1722,6 @@ const bindMemberFunctions = inst => {
1716
1722
  }
1717
1723
  });
1718
1724
  };
1719
- const SUPPORT_NOTICE_KEY = '__i18next_supportNoticeShown';
1720
- const getSupportNoticeShown = () => {
1721
- if (typeof globalThis !== 'undefined' && !!globalThis[SUPPORT_NOTICE_KEY]) return true;
1722
- if (typeof process !== 'undefined' && process.env && process.env.I18NEXT_NO_SUPPORT_NOTICE) return true;
1723
- return false;
1724
- };
1725
- const setSupportNoticeShown = () => {
1726
- if (typeof globalThis !== 'undefined') globalThis[SUPPORT_NOTICE_KEY] = true;
1727
- };
1728
- const usesLocize = inst => {
1729
- if (inst?.modules?.backend?.name?.indexOf('Locize') > 0) return true;
1730
- if (inst?.modules?.backend?.constructor?.name?.indexOf('Locize') > 0) return true;
1731
- if (inst?.options?.backend?.backends) {
1732
- if (inst.options.backend.backends.some(b => b?.name?.indexOf('Locize') > 0 || b?.constructor?.name?.indexOf('Locize') > 0)) return true;
1733
- }
1734
- if (inst?.options?.backend?.projectId) return true;
1735
- if (inst?.options?.backend?.backendOptions) {
1736
- if (inst.options.backend.backendOptions.some(b => b?.projectId)) return true;
1737
- }
1738
- return false;
1739
- };
1740
1725
  class I18n extends EventEmitter {
1741
1726
  constructor(options = {}, callback) {
1742
1727
  super();
@@ -1766,7 +1751,7 @@ class I18n extends EventEmitter {
1766
1751
  if (options.defaultNS == null && options.ns) {
1767
1752
  if (isString(options.ns)) {
1768
1753
  options.defaultNS = options.ns;
1769
- } else if (options.ns.indexOf('translation') < 0) {
1754
+ } else if (!options.ns.includes('translation')) {
1770
1755
  options.defaultNS = options.ns[0];
1771
1756
  }
1772
1757
  }
@@ -1789,10 +1774,6 @@ class I18n extends EventEmitter {
1789
1774
  if (typeof this.options.overloadTranslationOptionHandler !== 'function') {
1790
1775
  this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
1791
1776
  }
1792
- if (this.options.showSupportNotice !== false && !usesLocize(this) && !getSupportNoticeShown()) {
1793
- if (typeof console !== 'undefined' && typeof console.info !== 'undefined') console.info('🌐 i18next is made possible by our own product, Locize — consider powering your project with managed localization (AI, CDN, integrations): https://locize.com 💙');
1794
- setSupportNoticeShown();
1795
- }
1796
1777
  const createClassOnDemand = ClassOrObject => {
1797
1778
  if (!ClassOrObject) return null;
1798
1779
  if (typeof ClassOrObject === 'function') return new ClassOrObject();
@@ -1817,14 +1798,9 @@ class I18n extends EventEmitter {
1817
1798
  s.resourceStore = this.store;
1818
1799
  s.languageUtils = lu;
1819
1800
  s.pluralResolver = new PluralResolver(lu, {
1820
- prepend: this.options.pluralSeparator,
1821
- simplifyPluralSuffix: this.options.simplifyPluralSuffix
1801
+ prepend: this.options.pluralSeparator
1822
1802
  });
1823
- const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
1824
- if (usingLegacyFormatFunction) {
1825
- this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
1826
- }
1827
- if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
1803
+ if (formatter) {
1828
1804
  s.formatter = createClassOnDemand(formatter);
1829
1805
  if (s.formatter.init) s.formatter.init(s, this.options);
1830
1806
  this.options.interpolation.format = s.formatter.format.bind(s.formatter);
@@ -1907,7 +1883,7 @@ class I18n extends EventEmitter {
1907
1883
  const lngs = this.services.languageUtils.toResolveHierarchy(lng);
1908
1884
  lngs.forEach(l => {
1909
1885
  if (l === 'cimode') return;
1910
- if (toLoad.indexOf(l) < 0) toLoad.push(l);
1886
+ if (!toLoad.includes(l)) toLoad.push(l);
1911
1887
  });
1912
1888
  };
1913
1889
  if (!usedLng) {
@@ -1972,16 +1948,16 @@ class I18n extends EventEmitter {
1972
1948
  }
1973
1949
  setResolvedLanguage(l) {
1974
1950
  if (!l || !this.languages) return;
1975
- if (['cimode', 'dev'].indexOf(l) > -1) return;
1951
+ if (['cimode', 'dev'].includes(l)) return;
1976
1952
  for (let li = 0; li < this.languages.length; li++) {
1977
1953
  const lngInLngs = this.languages[li];
1978
- if (['cimode', 'dev'].indexOf(lngInLngs) > -1) continue;
1954
+ if (['cimode', 'dev'].includes(lngInLngs)) continue;
1979
1955
  if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
1980
1956
  this.resolvedLanguage = lngInLngs;
1981
1957
  break;
1982
1958
  }
1983
1959
  }
1984
- if (!this.resolvedLanguage && this.languages.indexOf(l) < 0 && this.store.hasLanguageSomeTranslations(l)) {
1960
+ if (!this.resolvedLanguage && !this.languages.includes(l) && this.store.hasLanguageSomeTranslations(l)) {
1985
1961
  this.resolvedLanguage = l;
1986
1962
  this.languages.unshift(l);
1987
1963
  }
@@ -2123,7 +2099,7 @@ class I18n extends EventEmitter {
2123
2099
  }
2124
2100
  if (isString(ns)) ns = [ns];
2125
2101
  ns.forEach(n => {
2126
- if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
2102
+ if (!this.options.ns.includes(n)) this.options.ns.push(n);
2127
2103
  });
2128
2104
  this.loadResources(err => {
2129
2105
  deferred.resolve();
@@ -2135,7 +2111,7 @@ class I18n extends EventEmitter {
2135
2111
  const deferred = defer();
2136
2112
  if (isString(lngs)) lngs = [lngs];
2137
2113
  const preloaded = this.options.preload || [];
2138
- const newLngs = lngs.filter(lng => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
2114
+ const newLngs = lngs.filter(lng => !preloaded.includes(lng) && this.services.languageUtils.isSupportedCode(lng));
2139
2115
  if (!newLngs.length) {
2140
2116
  if (callback) callback();
2141
2117
  return Promise.resolve();
@@ -2160,7 +2136,7 @@ class I18n extends EventEmitter {
2160
2136
  const rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ug', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam', 'ckb'];
2161
2137
  const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
2162
2138
  if (lng.toLowerCase().indexOf('-latn') > 1) return 'ltr';
2163
- return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
2139
+ return rtlLngs.includes(languageUtils.getLanguagePartFromCode(lng)) || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
2164
2140
  }
2165
2141
  static createInstance(options = {}, callback) {
2166
2142
  const instance = new I18n(options, callback);