@fkui/i18next-translate 6.39.0 → 6.41.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/dist/esm/index.js CHANGED
@@ -2078,7 +2078,7 @@ const defer = () => {
2078
2078
  };
2079
2079
  const makeString = object => {
2080
2080
  if (object == null) return '';
2081
- return '' + object;
2081
+ return String(object);
2082
2082
  };
2083
2083
  const copy = (a, s, t) => {
2084
2084
  a.forEach(m => {
@@ -2086,7 +2086,7 @@ const copy = (a, s, t) => {
2086
2086
  });
2087
2087
  };
2088
2088
  const lastOfPathSeparatorRegExp = /###/g;
2089
- const cleanKey = key => key && key.indexOf('###') > -1 ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
2089
+ const cleanKey = key => key && key.includes('###') ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
2090
2090
  const canNotTraverseDeeper = object => !object || isString(object);
2091
2091
  const getLastOfPath = (object, path, Empty) => {
2092
2092
  const stack = !isString(path) ? path : path.split('.');
@@ -2171,7 +2171,7 @@ const deepExtend = (target, source, overwrite) => {
2171
2171
  return target;
2172
2172
  };
2173
2173
  const regexEscape = str => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
2174
- var _entityMap = {
2174
+ const _entityMap = {
2175
2175
  '&': '&',
2176
2176
  '<': '&lt;',
2177
2177
  '>': '&gt;',
@@ -2210,7 +2210,7 @@ const looksLikeObjectPathRegExpCache = new RegExpCache(20);
2210
2210
  const looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
2211
2211
  nsSeparator = nsSeparator || '';
2212
2212
  keySeparator = keySeparator || '';
2213
- const possibleChars = chars.filter(c => nsSeparator.indexOf(c) < 0 && keySeparator.indexOf(c) < 0);
2213
+ const possibleChars = chars.filter(c => !nsSeparator.includes(c) && !keySeparator.includes(c));
2214
2214
  if (possibleChars.length === 0) return true;
2215
2215
  const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map(c => c === '?' ? '\\?' : c).join('|')})`);
2216
2216
  let matched = !r.test(key);
@@ -2243,7 +2243,7 @@ const deepFind = (obj, path, keySeparator = '.') => {
2243
2243
  nextPath += tokens[j];
2244
2244
  next = current[nextPath];
2245
2245
  if (next !== undefined) {
2246
- if (['string', 'number', 'boolean'].indexOf(typeof next) > -1 && j < tokens.length - 1) {
2246
+ if (['string', 'number', 'boolean'].includes(typeof next) && j < tokens.length - 1) {
2247
2247
  continue;
2248
2248
  }
2249
2249
  i += j - i + 1;
@@ -2334,6 +2334,14 @@ class EventEmitter {
2334
2334
  }
2335
2335
  this.observers[event].delete(listener);
2336
2336
  }
2337
+ once(event, listener) {
2338
+ const wrapper = (...args) => {
2339
+ listener(...args);
2340
+ this.off(event, wrapper);
2341
+ };
2342
+ this.on(event, wrapper);
2343
+ return this;
2344
+ }
2337
2345
  emit(event, ...args) {
2338
2346
  if (this.observers[event]) {
2339
2347
  const cloned = Array.from(this.observers[event].entries());
@@ -2347,7 +2355,7 @@ class EventEmitter {
2347
2355
  const cloned = Array.from(this.observers['*'].entries());
2348
2356
  cloned.forEach(([observer, numTimesAdded]) => {
2349
2357
  for (let i = 0; i < numTimesAdded; i++) {
2350
- observer.apply(observer, [event, ...args]);
2358
+ observer(event, ...args);
2351
2359
  }
2352
2360
  });
2353
2361
  }
@@ -2370,7 +2378,7 @@ class ResourceStore extends EventEmitter {
2370
2378
  }
2371
2379
  }
2372
2380
  addNamespaces(ns) {
2373
- if (this.options.ns.indexOf(ns) < 0) {
2381
+ if (!this.options.ns.includes(ns)) {
2374
2382
  this.options.ns.push(ns);
2375
2383
  }
2376
2384
  }
@@ -2384,7 +2392,7 @@ class ResourceStore extends EventEmitter {
2384
2392
  const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
2385
2393
  const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
2386
2394
  let path;
2387
- if (lng.indexOf('.') > -1) {
2395
+ if (lng.includes('.')) {
2388
2396
  path = lng.split('.');
2389
2397
  } else {
2390
2398
  path = [lng, ns];
@@ -2399,7 +2407,7 @@ class ResourceStore extends EventEmitter {
2399
2407
  }
2400
2408
  }
2401
2409
  const result = getPath(this.data, path);
2402
- if (!result && !ns && !key && lng.indexOf('.') > -1) {
2410
+ if (!result && !ns && !key && lng.includes('.')) {
2403
2411
  lng = path[0];
2404
2412
  ns = path[1];
2405
2413
  key = path.slice(2).join('.');
@@ -2413,7 +2421,7 @@ class ResourceStore extends EventEmitter {
2413
2421
  const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
2414
2422
  let path = [lng, ns];
2415
2423
  if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
2416
- if (lng.indexOf('.') > -1) {
2424
+ if (lng.includes('.')) {
2417
2425
  path = lng.split('.');
2418
2426
  value = ns;
2419
2427
  ns = path[1];
@@ -2437,7 +2445,7 @@ class ResourceStore extends EventEmitter {
2437
2445
  skipCopy: false
2438
2446
  }) {
2439
2447
  let path = [lng, ns];
2440
- if (lng.indexOf('.') > -1) {
2448
+ if (lng.includes('.')) {
2441
2449
  path = lng.split('.');
2442
2450
  deep = resources;
2443
2451
  resources = ns;
@@ -2515,10 +2523,18 @@ function keysFromSelector(selector, opts) {
2515
2523
  const {
2516
2524
  [PATH_KEY]: path
2517
2525
  } = selector(createProxy());
2518
- return path.join(opts?.keySeparator ?? '.');
2526
+ const keySeparator = opts?.keySeparator ?? '.';
2527
+ const nsSeparator = opts?.nsSeparator ?? ':';
2528
+ if (path.length > 1 && nsSeparator) {
2529
+ const ns = opts?.ns;
2530
+ const nsArray = Array.isArray(ns) ? ns : null;
2531
+ if (nsArray && nsArray.length > 1 && nsArray.slice(1).includes(path[0])) {
2532
+ return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
2533
+ }
2534
+ }
2535
+ return path.join(keySeparator);
2519
2536
  }
2520
2537
 
2521
- const checkedLoadedFor = {};
2522
2538
  const shouldHandleAsObject = res => !isString(res) && typeof res !== 'boolean' && typeof res !== 'number';
2523
2539
  class Translator extends EventEmitter {
2524
2540
  constructor(services, options = {}) {
@@ -2529,6 +2545,7 @@ class Translator extends EventEmitter {
2529
2545
  this.options.keySeparator = '.';
2530
2546
  }
2531
2547
  this.logger = baseLogger.create('translator');
2548
+ this.checkedLoadedFor = {};
2532
2549
  }
2533
2550
  changeLanguage(lng) {
2534
2551
  if (lng) this.language = lng;
@@ -2553,7 +2570,7 @@ class Translator extends EventEmitter {
2553
2570
  if (nsSeparator === undefined) nsSeparator = ':';
2554
2571
  const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
2555
2572
  let namespaces = opt.ns || this.options.defaultNS || [];
2556
- const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1;
2573
+ const wouldCheckForNsInKey = nsSeparator && key.includes(nsSeparator);
2557
2574
  const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !opt.keySeparator && !this.options.userDefinedNsSeparator && !opt.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
2558
2575
  if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
2559
2576
  const m = key.match(this.interpolator.nestingRegexp);
@@ -2564,7 +2581,7 @@ class Translator extends EventEmitter {
2564
2581
  };
2565
2582
  }
2566
2583
  const parts = key.split(nsSeparator);
2567
- if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
2584
+ if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.includes(parts[0])) namespaces = parts.shift();
2568
2585
  key = parts.join(keySeparator);
2569
2586
  }
2570
2587
  return {
@@ -2589,6 +2606,10 @@ class Translator extends EventEmitter {
2589
2606
  ...opt
2590
2607
  });
2591
2608
  if (!Array.isArray(keys)) keys = [String(keys)];
2609
+ keys = keys.map(k => typeof k === 'function' ? keysFromSelector(k, {
2610
+ ...this.options,
2611
+ ...opt
2612
+ }) : String(k));
2592
2613
  const returnDetails = opt.returnDetails !== undefined ? opt.returnDetails : this.options.returnDetails;
2593
2614
  const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
2594
2615
  const {
@@ -2647,7 +2668,7 @@ class Translator extends EventEmitter {
2647
2668
  }
2648
2669
  const handleAsObject = shouldHandleAsObject(resForObjHndl);
2649
2670
  const resType = Object.prototype.toString.apply(resForObjHndl);
2650
- if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
2671
+ if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && !noObject.includes(resType) && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
2651
2672
  if (!opt.returnObjects && !this.options.returnObjects) {
2652
2673
  if (!this.options.returnedObjectHandler) {
2653
2674
  this.logger.warn('accessing an object - but returnObjects options is not enabled!');
@@ -2743,7 +2764,7 @@ class Translator extends EventEmitter {
2743
2764
  if (this.options.saveMissingPlurals && needsPluralHandling) {
2744
2765
  lngs.forEach(language => {
2745
2766
  const suffixes = this.pluralResolver.getSuffixes(language, opt);
2746
- if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) {
2767
+ if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && !suffixes.includes(`${this.options.pluralSeparator}zero`)) {
2747
2768
  suffixes.push(`${this.options.pluralSeparator}zero`);
2748
2769
  }
2749
2770
  suffixes.forEach(suffix => {
@@ -2835,6 +2856,10 @@ class Translator extends EventEmitter {
2835
2856
  let usedLng;
2836
2857
  let usedNS;
2837
2858
  if (isString(keys)) keys = [keys];
2859
+ if (Array.isArray(keys)) keys = keys.map(k => typeof k === 'function' ? keysFromSelector(k, {
2860
+ ...this.options,
2861
+ ...opt
2862
+ }) : k);
2838
2863
  keys.forEach(k => {
2839
2864
  if (this.isValidLookup(found)) return;
2840
2865
  const extracted = this.extractFromKey(k, opt);
@@ -2849,8 +2874,8 @@ class Translator extends EventEmitter {
2849
2874
  namespaces.forEach(ns => {
2850
2875
  if (this.isValidLookup(found)) return;
2851
2876
  usedNS = ns;
2852
- if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
2853
- checkedLoadedFor[`${codes[0]}-${ns}`] = true;
2877
+ if (!this.checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
2878
+ this.checkedLoadedFor[`${codes[0]}-${ns}`] = true;
2854
2879
  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!!!');
2855
2880
  }
2856
2881
  codes.forEach(code => {
@@ -2865,7 +2890,7 @@ class Translator extends EventEmitter {
2865
2890
  const zeroSuffix = `${this.options.pluralSeparator}zero`;
2866
2891
  const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
2867
2892
  if (needsPluralHandling) {
2868
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
2893
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
2869
2894
  finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
2870
2895
  }
2871
2896
  finalKeys.push(key + pluralSuffix);
@@ -2877,7 +2902,7 @@ class Translator extends EventEmitter {
2877
2902
  const contextKey = `${key}${this.options.contextSeparator || '_'}${opt.context}`;
2878
2903
  finalKeys.push(contextKey);
2879
2904
  if (needsPluralHandling) {
2880
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
2905
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
2881
2906
  finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
2882
2907
  }
2883
2908
  finalKeys.push(contextKey + pluralSuffix);
@@ -2938,7 +2963,7 @@ class Translator extends EventEmitter {
2938
2963
  static hasDefaultValue(options) {
2939
2964
  const prefix = 'defaultValue';
2940
2965
  for (const option in options) {
2941
- if (Object.prototype.hasOwnProperty.call(options, option) && prefix === option.substring(0, prefix.length) && undefined !== options[option]) {
2966
+ if (Object.prototype.hasOwnProperty.call(options, option) && option.startsWith(prefix) && undefined !== options[option]) {
2942
2967
  return true;
2943
2968
  }
2944
2969
  }
@@ -2954,7 +2979,7 @@ class LanguageUtil {
2954
2979
  }
2955
2980
  getScriptPartFromCode(code) {
2956
2981
  code = getCleanedCode(code);
2957
- if (!code || code.indexOf('-') < 0) return null;
2982
+ if (!code || !code.includes('-')) return null;
2958
2983
  const p = code.split('-');
2959
2984
  if (p.length === 2) return null;
2960
2985
  p.pop();
@@ -2963,12 +2988,12 @@ class LanguageUtil {
2963
2988
  }
2964
2989
  getLanguagePartFromCode(code) {
2965
2990
  code = getCleanedCode(code);
2966
- if (!code || code.indexOf('-') < 0) return code;
2991
+ if (!code || !code.includes('-')) return code;
2967
2992
  const p = code.split('-');
2968
2993
  return this.formatLanguageCode(p[0]);
2969
2994
  }
2970
2995
  formatLanguageCode(code) {
2971
- if (isString(code) && code.indexOf('-') > -1) {
2996
+ if (isString(code) && code.includes('-')) {
2972
2997
  let formattedCode;
2973
2998
  try {
2974
2999
  formattedCode = Intl.getCanonicalLocales(code)[0];
@@ -2988,7 +3013,7 @@ class LanguageUtil {
2988
3013
  if (this.options.load === 'languageOnly' || this.options.nonExplicitSupportedLngs) {
2989
3014
  code = this.getLanguagePartFromCode(code);
2990
3015
  }
2991
- return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1;
3016
+ return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.includes(code);
2992
3017
  }
2993
3018
  getBestMatchFromCodes(codes) {
2994
3019
  if (!codes) return null;
@@ -3006,10 +3031,11 @@ class LanguageUtil {
3006
3031
  const lngOnly = this.getLanguagePartFromCode(code);
3007
3032
  if (this.isSupportedCode(lngOnly)) return found = lngOnly;
3008
3033
  found = this.options.supportedLngs.find(supportedLng => {
3009
- if (supportedLng === lngOnly) return supportedLng;
3010
- if (supportedLng.indexOf('-') < 0 && lngOnly.indexOf('-') < 0) return;
3011
- if (supportedLng.indexOf('-') > 0 && lngOnly.indexOf('-') < 0 && supportedLng.substring(0, supportedLng.indexOf('-')) === lngOnly) return supportedLng;
3012
- if (supportedLng.indexOf(lngOnly) === 0 && lngOnly.length > 1) return supportedLng;
3034
+ if (supportedLng === lngOnly) return true;
3035
+ if (!supportedLng.includes('-') && !lngOnly.includes('-')) return false;
3036
+ if (supportedLng.includes('-') && !lngOnly.includes('-') && supportedLng.slice(0, supportedLng.indexOf('-')) === lngOnly) return true;
3037
+ if (supportedLng.startsWith(lngOnly) && lngOnly.length > 1) return true;
3038
+ return false;
3013
3039
  });
3014
3040
  });
3015
3041
  }
@@ -3040,7 +3066,7 @@ class LanguageUtil {
3040
3066
  this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
3041
3067
  }
3042
3068
  };
3043
- if (isString(code) && (code.indexOf('-') > -1 || code.indexOf('_') > -1)) {
3069
+ if (isString(code) && (code.includes('-') || code.includes('_'))) {
3044
3070
  if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code));
3045
3071
  if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code));
3046
3072
  if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code));
@@ -3048,7 +3074,7 @@ class LanguageUtil {
3048
3074
  addCode(this.formatLanguageCode(code));
3049
3075
  }
3050
3076
  fallbackCodes.forEach(fc => {
3051
- if (codes.indexOf(fc) < 0) addCode(this.formatLanguageCode(fc));
3077
+ if (!codes.includes(fc)) addCode(this.formatLanguageCode(fc));
3052
3078
  });
3053
3079
  return codes;
3054
3080
  }
@@ -3204,7 +3230,7 @@ class Interpolator {
3204
3230
  let replaces;
3205
3231
  const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
3206
3232
  const handleFormat = key => {
3207
- if (key.indexOf(this.formatSeparator) < 0) {
3233
+ if (!key.includes(this.formatSeparator)) {
3208
3234
  const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
3209
3235
  return this.alwaysFormat ? this.format(path, undefined, lng, {
3210
3236
  ...options,
@@ -3274,7 +3300,7 @@ class Interpolator {
3274
3300
  let clonedOptions;
3275
3301
  const handleHasOptions = (key, inheritedOptions) => {
3276
3302
  const sep = this.nestingOptionsSeparator;
3277
- if (key.indexOf(sep) < 0) return key;
3303
+ if (!key.includes(sep)) return key;
3278
3304
  const c = key.split(new RegExp(`${regexEscape(sep)}[ ]*{`));
3279
3305
  let optionsString = `{${c[1]}`;
3280
3306
  key = c[0];
@@ -3294,7 +3320,7 @@ class Interpolator {
3294
3320
  this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
3295
3321
  return `${key}${sep}${optionsString}`;
3296
3322
  }
3297
- if (clonedOptions.defaultValue && clonedOptions.defaultValue.indexOf(this.prefix) > -1) delete clonedOptions.defaultValue;
3323
+ if (clonedOptions.defaultValue && clonedOptions.defaultValue.includes(this.prefix)) delete clonedOptions.defaultValue;
3298
3324
  return key;
3299
3325
  };
3300
3326
  while (match = this.nestingRegexp.exec(str)) {
@@ -3333,13 +3359,13 @@ class Interpolator {
3333
3359
  const parseFormatStr = formatStr => {
3334
3360
  let formatName = formatStr.toLowerCase().trim();
3335
3361
  const formatOptions = {};
3336
- if (formatStr.indexOf('(') > -1) {
3362
+ if (formatStr.includes('(')) {
3337
3363
  const p = formatStr.split('(');
3338
3364
  formatName = p[0].toLowerCase().trim();
3339
- const optStr = p[1].substring(0, p[1].length - 1);
3340
- if (formatName === 'currency' && optStr.indexOf(':') < 0) {
3365
+ const optStr = p[1].slice(0, -1);
3366
+ if (formatName === 'currency' && !optStr.includes(':')) {
3341
3367
  if (!formatOptions.currency) formatOptions.currency = optStr.trim();
3342
- } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
3368
+ } else if (formatName === 'relativetime' && !optStr.includes(':')) {
3343
3369
  if (!formatOptions.range) formatOptions.range = optStr.trim();
3344
3370
  } else {
3345
3371
  const opts = optStr.split(';');
@@ -3433,9 +3459,11 @@ class Formatter {
3433
3459
  this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
3434
3460
  }
3435
3461
  format(value, format, lng, options = {}) {
3462
+ if (!format) return value;
3463
+ if (value == null) return value;
3436
3464
  const formats = format.split(this.formatSeparator);
3437
- if (formats.length > 1 && formats[0].indexOf('(') > 1 && formats[0].indexOf(')') < 0 && formats.find(f => f.indexOf(')') > -1)) {
3438
- const lastIndex = formats.findIndex(f => f.indexOf(')') > -1);
3465
+ if (formats.length > 1 && formats[0].indexOf('(') > 1 && !formats[0].includes(')') && formats.find(f => f.includes(')'))) {
3466
+ const lastIndex = formats.findIndex(f => f.includes(')'));
3439
3467
  formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
3440
3468
  }
3441
3469
  const result = formats.reduce((mem, f) => {
@@ -3589,7 +3617,7 @@ class Connector extends EventEmitter {
3589
3617
  }
3590
3618
  if (err && data && tried < this.maxRetries) {
3591
3619
  setTimeout(() => {
3592
- this.read.call(this, lng, ns, fcName, tried + 1, wait * 2, callback);
3620
+ this.read(lng, ns, fcName, tried + 1, wait * 2, callback);
3593
3621
  }, wait);
3594
3622
  return;
3595
3623
  }
@@ -3693,7 +3721,6 @@ const get = () => ({
3693
3721
  nonExplicitSupportedLngs: false,
3694
3722
  load: 'all',
3695
3723
  preload: false,
3696
- simplifyPluralSuffix: true,
3697
3724
  keySeparator: '.',
3698
3725
  nsSeparator: ':',
3699
3726
  pluralSeparator: '_',
@@ -3730,7 +3757,6 @@ const get = () => ({
3730
3757
  },
3731
3758
  interpolation: {
3732
3759
  escapeValue: true,
3733
- format: value => value,
3734
3760
  prefix: '{{',
3735
3761
  suffix: '}}',
3736
3762
  formatSeparator: ',',
@@ -3747,10 +3773,9 @@ const transformOptions = options => {
3747
3773
  if (isString(options.ns)) options.ns = [options.ns];
3748
3774
  if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
3749
3775
  if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
3750
- if (options.supportedLngs?.indexOf?.('cimode') < 0) {
3776
+ if (options.supportedLngs && !options.supportedLngs.includes('cimode')) {
3751
3777
  options.supportedLngs = options.supportedLngs.concat(['cimode']);
3752
3778
  }
3753
- if (typeof options.initImmediate === 'boolean') options.initAsync = options.initImmediate;
3754
3779
  return options;
3755
3780
  };
3756
3781
 
@@ -3763,23 +3788,6 @@ const bindMemberFunctions = inst => {
3763
3788
  }
3764
3789
  });
3765
3790
  };
3766
- const SUPPORT_NOTICE_KEY = '__i18next_supportNoticeShown';
3767
- const getSupportNoticeShown = () => typeof globalThis !== 'undefined' && !!globalThis[SUPPORT_NOTICE_KEY];
3768
- const setSupportNoticeShown = () => {
3769
- if (typeof globalThis !== 'undefined') globalThis[SUPPORT_NOTICE_KEY] = true;
3770
- };
3771
- const usesLocize = inst => {
3772
- if (inst?.modules?.backend?.name?.indexOf('Locize') > 0) return true;
3773
- if (inst?.modules?.backend?.constructor?.name?.indexOf('Locize') > 0) return true;
3774
- if (inst?.options?.backend?.backends) {
3775
- if (inst.options.backend.backends.some(b => b?.name?.indexOf('Locize') > 0 || b?.constructor?.name?.indexOf('Locize') > 0)) return true;
3776
- }
3777
- if (inst?.options?.backend?.projectId) return true;
3778
- if (inst?.options?.backend?.backendOptions) {
3779
- if (inst.options.backend.backendOptions.some(b => b?.projectId)) return true;
3780
- }
3781
- return false;
3782
- };
3783
3791
  class I18n extends EventEmitter {
3784
3792
  constructor(options = {}, callback) {
3785
3793
  super();
@@ -3809,7 +3817,7 @@ class I18n extends EventEmitter {
3809
3817
  if (options.defaultNS == null && options.ns) {
3810
3818
  if (isString(options.ns)) {
3811
3819
  options.defaultNS = options.ns;
3812
- } else if (options.ns.indexOf('translation') < 0) {
3820
+ } else if (!options.ns.includes('translation')) {
3813
3821
  options.defaultNS = options.ns[0];
3814
3822
  }
3815
3823
  }
@@ -3832,10 +3840,6 @@ class I18n extends EventEmitter {
3832
3840
  if (typeof this.options.overloadTranslationOptionHandler !== 'function') {
3833
3841
  this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
3834
3842
  }
3835
- if (this.options.showSupportNotice !== false && !usesLocize(this) && !getSupportNoticeShown()) {
3836
- if (typeof console !== 'undefined' && typeof console.info !== 'undefined') console.info('🌐 i18next is maintained with support from Locize — consider powering your project with managed localization (AI, CDN, integrations): https://locize.com 💙');
3837
- setSupportNoticeShown();
3838
- }
3839
3843
  const createClassOnDemand = ClassOrObject => {
3840
3844
  if (!ClassOrObject) return null;
3841
3845
  if (typeof ClassOrObject === 'function') return new ClassOrObject();
@@ -3860,14 +3864,9 @@ class I18n extends EventEmitter {
3860
3864
  s.resourceStore = this.store;
3861
3865
  s.languageUtils = lu;
3862
3866
  s.pluralResolver = new PluralResolver(lu, {
3863
- prepend: this.options.pluralSeparator,
3864
- simplifyPluralSuffix: this.options.simplifyPluralSuffix
3867
+ prepend: this.options.pluralSeparator
3865
3868
  });
3866
- const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
3867
- if (usingLegacyFormatFunction) {
3868
- this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
3869
- }
3870
- if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
3869
+ if (formatter) {
3871
3870
  s.formatter = createClassOnDemand(formatter);
3872
3871
  if (s.formatter.init) s.formatter.init(s, this.options);
3873
3872
  this.options.interpolation.format = s.formatter.format.bind(s.formatter);
@@ -3950,7 +3949,7 @@ class I18n extends EventEmitter {
3950
3949
  const lngs = this.services.languageUtils.toResolveHierarchy(lng);
3951
3950
  lngs.forEach(l => {
3952
3951
  if (l === 'cimode') return;
3953
- if (toLoad.indexOf(l) < 0) toLoad.push(l);
3952
+ if (!toLoad.includes(l)) toLoad.push(l);
3954
3953
  });
3955
3954
  };
3956
3955
  if (!usedLng) {
@@ -4015,16 +4014,16 @@ class I18n extends EventEmitter {
4015
4014
  }
4016
4015
  setResolvedLanguage(l) {
4017
4016
  if (!l || !this.languages) return;
4018
- if (['cimode', 'dev'].indexOf(l) > -1) return;
4017
+ if (['cimode', 'dev'].includes(l)) return;
4019
4018
  for (let li = 0; li < this.languages.length; li++) {
4020
4019
  const lngInLngs = this.languages[li];
4021
- if (['cimode', 'dev'].indexOf(lngInLngs) > -1) continue;
4020
+ if (['cimode', 'dev'].includes(lngInLngs)) continue;
4022
4021
  if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
4023
4022
  this.resolvedLanguage = lngInLngs;
4024
4023
  break;
4025
4024
  }
4026
4025
  }
4027
- if (!this.resolvedLanguage && this.languages.indexOf(l) < 0 && this.store.hasLanguageSomeTranslations(l)) {
4026
+ if (!this.resolvedLanguage && !this.languages.includes(l) && this.store.hasLanguageSomeTranslations(l)) {
4028
4027
  this.resolvedLanguage = l;
4029
4028
  this.languages.unshift(l);
4030
4029
  }
@@ -4096,21 +4095,20 @@ class I18n extends EventEmitter {
4096
4095
  o.lngs = o.lngs || fixedT.lngs;
4097
4096
  o.ns = o.ns || fixedT.ns;
4098
4097
  if (o.keyPrefix !== '') o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
4098
+ const selectorOpts = {
4099
+ ...this.options,
4100
+ ...o
4101
+ };
4102
+ if (typeof o.keyPrefix === 'function') o.keyPrefix = keysFromSelector(o.keyPrefix, selectorOpts);
4099
4103
  const keySeparator = this.options.keySeparator || '.';
4100
4104
  let resultKey;
4101
4105
  if (o.keyPrefix && Array.isArray(key)) {
4102
4106
  resultKey = key.map(k => {
4103
- if (typeof k === 'function') k = keysFromSelector(k, {
4104
- ...this.options,
4105
- ...opts
4106
- });
4107
+ if (typeof k === 'function') k = keysFromSelector(k, selectorOpts);
4107
4108
  return `${o.keyPrefix}${keySeparator}${k}`;
4108
4109
  });
4109
4110
  } else {
4110
- if (typeof key === 'function') key = keysFromSelector(key, {
4111
- ...this.options,
4112
- ...opts
4113
- });
4111
+ if (typeof key === 'function') key = keysFromSelector(key, selectorOpts);
4114
4112
  resultKey = o.keyPrefix ? `${o.keyPrefix}${keySeparator}${key}` : key;
4115
4113
  }
4116
4114
  return this.t(resultKey, o);
@@ -4167,7 +4165,7 @@ class I18n extends EventEmitter {
4167
4165
  }
4168
4166
  if (isString(ns)) ns = [ns];
4169
4167
  ns.forEach(n => {
4170
- if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
4168
+ if (!this.options.ns.includes(n)) this.options.ns.push(n);
4171
4169
  });
4172
4170
  this.loadResources(err => {
4173
4171
  deferred.resolve();
@@ -4179,7 +4177,7 @@ class I18n extends EventEmitter {
4179
4177
  const deferred = defer();
4180
4178
  if (isString(lngs)) lngs = [lngs];
4181
4179
  const preloaded = this.options.preload || [];
4182
- const newLngs = lngs.filter(lng => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
4180
+ const newLngs = lngs.filter(lng => !preloaded.includes(lng) && this.services.languageUtils.isSupportedCode(lng));
4183
4181
  if (!newLngs.length) {
4184
4182
  if (callback) callback();
4185
4183
  return Promise.resolve();
@@ -4204,7 +4202,7 @@ class I18n extends EventEmitter {
4204
4202
  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'];
4205
4203
  const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
4206
4204
  if (lng.toLowerCase().indexOf('-latn') > 1) return 'ltr';
4207
- return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
4205
+ return rtlLngs.includes(languageUtils.getLanguagePartFromCode(lng)) || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
4208
4206
  }
4209
4207
  static createInstance(options = {}, callback) {
4210
4208
  const instance = new I18n(options, callback);