@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/cjs/index.js CHANGED
@@ -2080,7 +2080,7 @@ const defer = () => {
2080
2080
  };
2081
2081
  const makeString = object => {
2082
2082
  if (object == null) return '';
2083
- return '' + object;
2083
+ return String(object);
2084
2084
  };
2085
2085
  const copy = (a, s, t) => {
2086
2086
  a.forEach(m => {
@@ -2088,7 +2088,7 @@ const copy = (a, s, t) => {
2088
2088
  });
2089
2089
  };
2090
2090
  const lastOfPathSeparatorRegExp = /###/g;
2091
- const cleanKey = key => key && key.indexOf('###') > -1 ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
2091
+ const cleanKey = key => key && key.includes('###') ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
2092
2092
  const canNotTraverseDeeper = object => !object || isString(object);
2093
2093
  const getLastOfPath = (object, path, Empty) => {
2094
2094
  const stack = !isString(path) ? path : path.split('.');
@@ -2173,7 +2173,7 @@ const deepExtend = (target, source, overwrite) => {
2173
2173
  return target;
2174
2174
  };
2175
2175
  const regexEscape = str => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
2176
- var _entityMap = {
2176
+ const _entityMap = {
2177
2177
  '&': '&',
2178
2178
  '<': '&lt;',
2179
2179
  '>': '&gt;',
@@ -2212,7 +2212,7 @@ const looksLikeObjectPathRegExpCache = new RegExpCache(20);
2212
2212
  const looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
2213
2213
  nsSeparator = nsSeparator || '';
2214
2214
  keySeparator = keySeparator || '';
2215
- const possibleChars = chars.filter(c => nsSeparator.indexOf(c) < 0 && keySeparator.indexOf(c) < 0);
2215
+ const possibleChars = chars.filter(c => !nsSeparator.includes(c) && !keySeparator.includes(c));
2216
2216
  if (possibleChars.length === 0) return true;
2217
2217
  const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map(c => c === '?' ? '\\?' : c).join('|')})`);
2218
2218
  let matched = !r.test(key);
@@ -2245,7 +2245,7 @@ const deepFind = (obj, path, keySeparator = '.') => {
2245
2245
  nextPath += tokens[j];
2246
2246
  next = current[nextPath];
2247
2247
  if (next !== undefined) {
2248
- if (['string', 'number', 'boolean'].indexOf(typeof next) > -1 && j < tokens.length - 1) {
2248
+ if (['string', 'number', 'boolean'].includes(typeof next) && j < tokens.length - 1) {
2249
2249
  continue;
2250
2250
  }
2251
2251
  i += j - i + 1;
@@ -2336,6 +2336,14 @@ class EventEmitter {
2336
2336
  }
2337
2337
  this.observers[event].delete(listener);
2338
2338
  }
2339
+ once(event, listener) {
2340
+ const wrapper = (...args) => {
2341
+ listener(...args);
2342
+ this.off(event, wrapper);
2343
+ };
2344
+ this.on(event, wrapper);
2345
+ return this;
2346
+ }
2339
2347
  emit(event, ...args) {
2340
2348
  if (this.observers[event]) {
2341
2349
  const cloned = Array.from(this.observers[event].entries());
@@ -2349,7 +2357,7 @@ class EventEmitter {
2349
2357
  const cloned = Array.from(this.observers['*'].entries());
2350
2358
  cloned.forEach(([observer, numTimesAdded]) => {
2351
2359
  for (let i = 0; i < numTimesAdded; i++) {
2352
- observer.apply(observer, [event, ...args]);
2360
+ observer(event, ...args);
2353
2361
  }
2354
2362
  });
2355
2363
  }
@@ -2372,7 +2380,7 @@ class ResourceStore extends EventEmitter {
2372
2380
  }
2373
2381
  }
2374
2382
  addNamespaces(ns) {
2375
- if (this.options.ns.indexOf(ns) < 0) {
2383
+ if (!this.options.ns.includes(ns)) {
2376
2384
  this.options.ns.push(ns);
2377
2385
  }
2378
2386
  }
@@ -2386,7 +2394,7 @@ class ResourceStore extends EventEmitter {
2386
2394
  const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
2387
2395
  const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
2388
2396
  let path;
2389
- if (lng.indexOf('.') > -1) {
2397
+ if (lng.includes('.')) {
2390
2398
  path = lng.split('.');
2391
2399
  } else {
2392
2400
  path = [lng, ns];
@@ -2401,7 +2409,7 @@ class ResourceStore extends EventEmitter {
2401
2409
  }
2402
2410
  }
2403
2411
  const result = getPath(this.data, path);
2404
- if (!result && !ns && !key && lng.indexOf('.') > -1) {
2412
+ if (!result && !ns && !key && lng.includes('.')) {
2405
2413
  lng = path[0];
2406
2414
  ns = path[1];
2407
2415
  key = path.slice(2).join('.');
@@ -2415,7 +2423,7 @@ class ResourceStore extends EventEmitter {
2415
2423
  const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
2416
2424
  let path = [lng, ns];
2417
2425
  if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
2418
- if (lng.indexOf('.') > -1) {
2426
+ if (lng.includes('.')) {
2419
2427
  path = lng.split('.');
2420
2428
  value = ns;
2421
2429
  ns = path[1];
@@ -2439,7 +2447,7 @@ class ResourceStore extends EventEmitter {
2439
2447
  skipCopy: false
2440
2448
  }) {
2441
2449
  let path = [lng, ns];
2442
- if (lng.indexOf('.') > -1) {
2450
+ if (lng.includes('.')) {
2443
2451
  path = lng.split('.');
2444
2452
  deep = resources;
2445
2453
  resources = ns;
@@ -2517,10 +2525,18 @@ function keysFromSelector(selector, opts) {
2517
2525
  const {
2518
2526
  [PATH_KEY]: path
2519
2527
  } = selector(createProxy());
2520
- return path.join(opts?.keySeparator ?? '.');
2528
+ const keySeparator = opts?.keySeparator ?? '.';
2529
+ const nsSeparator = opts?.nsSeparator ?? ':';
2530
+ if (path.length > 1 && nsSeparator) {
2531
+ const ns = opts?.ns;
2532
+ const nsArray = Array.isArray(ns) ? ns : null;
2533
+ if (nsArray && nsArray.length > 1 && nsArray.slice(1).includes(path[0])) {
2534
+ return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
2535
+ }
2536
+ }
2537
+ return path.join(keySeparator);
2521
2538
  }
2522
2539
 
2523
- const checkedLoadedFor = {};
2524
2540
  const shouldHandleAsObject = res => !isString(res) && typeof res !== 'boolean' && typeof res !== 'number';
2525
2541
  class Translator extends EventEmitter {
2526
2542
  constructor(services, options = {}) {
@@ -2531,6 +2547,7 @@ class Translator extends EventEmitter {
2531
2547
  this.options.keySeparator = '.';
2532
2548
  }
2533
2549
  this.logger = baseLogger.create('translator');
2550
+ this.checkedLoadedFor = {};
2534
2551
  }
2535
2552
  changeLanguage(lng) {
2536
2553
  if (lng) this.language = lng;
@@ -2555,7 +2572,7 @@ class Translator extends EventEmitter {
2555
2572
  if (nsSeparator === undefined) nsSeparator = ':';
2556
2573
  const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
2557
2574
  let namespaces = opt.ns || this.options.defaultNS || [];
2558
- const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1;
2575
+ const wouldCheckForNsInKey = nsSeparator && key.includes(nsSeparator);
2559
2576
  const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !opt.keySeparator && !this.options.userDefinedNsSeparator && !opt.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
2560
2577
  if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
2561
2578
  const m = key.match(this.interpolator.nestingRegexp);
@@ -2566,7 +2583,7 @@ class Translator extends EventEmitter {
2566
2583
  };
2567
2584
  }
2568
2585
  const parts = key.split(nsSeparator);
2569
- if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
2586
+ if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.includes(parts[0])) namespaces = parts.shift();
2570
2587
  key = parts.join(keySeparator);
2571
2588
  }
2572
2589
  return {
@@ -2591,6 +2608,10 @@ class Translator extends EventEmitter {
2591
2608
  ...opt
2592
2609
  });
2593
2610
  if (!Array.isArray(keys)) keys = [String(keys)];
2611
+ keys = keys.map(k => typeof k === 'function' ? keysFromSelector(k, {
2612
+ ...this.options,
2613
+ ...opt
2614
+ }) : String(k));
2594
2615
  const returnDetails = opt.returnDetails !== undefined ? opt.returnDetails : this.options.returnDetails;
2595
2616
  const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
2596
2617
  const {
@@ -2649,7 +2670,7 @@ class Translator extends EventEmitter {
2649
2670
  }
2650
2671
  const handleAsObject = shouldHandleAsObject(resForObjHndl);
2651
2672
  const resType = Object.prototype.toString.apply(resForObjHndl);
2652
- if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
2673
+ if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && !noObject.includes(resType) && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
2653
2674
  if (!opt.returnObjects && !this.options.returnObjects) {
2654
2675
  if (!this.options.returnedObjectHandler) {
2655
2676
  this.logger.warn('accessing an object - but returnObjects options is not enabled!');
@@ -2745,7 +2766,7 @@ class Translator extends EventEmitter {
2745
2766
  if (this.options.saveMissingPlurals && needsPluralHandling) {
2746
2767
  lngs.forEach(language => {
2747
2768
  const suffixes = this.pluralResolver.getSuffixes(language, opt);
2748
- if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) {
2769
+ if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && !suffixes.includes(`${this.options.pluralSeparator}zero`)) {
2749
2770
  suffixes.push(`${this.options.pluralSeparator}zero`);
2750
2771
  }
2751
2772
  suffixes.forEach(suffix => {
@@ -2837,6 +2858,10 @@ class Translator extends EventEmitter {
2837
2858
  let usedLng;
2838
2859
  let usedNS;
2839
2860
  if (isString(keys)) keys = [keys];
2861
+ if (Array.isArray(keys)) keys = keys.map(k => typeof k === 'function' ? keysFromSelector(k, {
2862
+ ...this.options,
2863
+ ...opt
2864
+ }) : k);
2840
2865
  keys.forEach(k => {
2841
2866
  if (this.isValidLookup(found)) return;
2842
2867
  const extracted = this.extractFromKey(k, opt);
@@ -2851,8 +2876,8 @@ class Translator extends EventEmitter {
2851
2876
  namespaces.forEach(ns => {
2852
2877
  if (this.isValidLookup(found)) return;
2853
2878
  usedNS = ns;
2854
- if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
2855
- checkedLoadedFor[`${codes[0]}-${ns}`] = true;
2879
+ if (!this.checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
2880
+ this.checkedLoadedFor[`${codes[0]}-${ns}`] = true;
2856
2881
  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!!!');
2857
2882
  }
2858
2883
  codes.forEach(code => {
@@ -2867,7 +2892,7 @@ class Translator extends EventEmitter {
2867
2892
  const zeroSuffix = `${this.options.pluralSeparator}zero`;
2868
2893
  const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
2869
2894
  if (needsPluralHandling) {
2870
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
2895
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
2871
2896
  finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
2872
2897
  }
2873
2898
  finalKeys.push(key + pluralSuffix);
@@ -2879,7 +2904,7 @@ class Translator extends EventEmitter {
2879
2904
  const contextKey = `${key}${this.options.contextSeparator || '_'}${opt.context}`;
2880
2905
  finalKeys.push(contextKey);
2881
2906
  if (needsPluralHandling) {
2882
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
2907
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
2883
2908
  finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
2884
2909
  }
2885
2910
  finalKeys.push(contextKey + pluralSuffix);
@@ -2940,7 +2965,7 @@ class Translator extends EventEmitter {
2940
2965
  static hasDefaultValue(options) {
2941
2966
  const prefix = 'defaultValue';
2942
2967
  for (const option in options) {
2943
- if (Object.prototype.hasOwnProperty.call(options, option) && prefix === option.substring(0, prefix.length) && undefined !== options[option]) {
2968
+ if (Object.prototype.hasOwnProperty.call(options, option) && option.startsWith(prefix) && undefined !== options[option]) {
2944
2969
  return true;
2945
2970
  }
2946
2971
  }
@@ -2956,7 +2981,7 @@ class LanguageUtil {
2956
2981
  }
2957
2982
  getScriptPartFromCode(code) {
2958
2983
  code = getCleanedCode(code);
2959
- if (!code || code.indexOf('-') < 0) return null;
2984
+ if (!code || !code.includes('-')) return null;
2960
2985
  const p = code.split('-');
2961
2986
  if (p.length === 2) return null;
2962
2987
  p.pop();
@@ -2965,12 +2990,12 @@ class LanguageUtil {
2965
2990
  }
2966
2991
  getLanguagePartFromCode(code) {
2967
2992
  code = getCleanedCode(code);
2968
- if (!code || code.indexOf('-') < 0) return code;
2993
+ if (!code || !code.includes('-')) return code;
2969
2994
  const p = code.split('-');
2970
2995
  return this.formatLanguageCode(p[0]);
2971
2996
  }
2972
2997
  formatLanguageCode(code) {
2973
- if (isString(code) && code.indexOf('-') > -1) {
2998
+ if (isString(code) && code.includes('-')) {
2974
2999
  let formattedCode;
2975
3000
  try {
2976
3001
  formattedCode = Intl.getCanonicalLocales(code)[0];
@@ -2990,7 +3015,7 @@ class LanguageUtil {
2990
3015
  if (this.options.load === 'languageOnly' || this.options.nonExplicitSupportedLngs) {
2991
3016
  code = this.getLanguagePartFromCode(code);
2992
3017
  }
2993
- return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1;
3018
+ return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.includes(code);
2994
3019
  }
2995
3020
  getBestMatchFromCodes(codes) {
2996
3021
  if (!codes) return null;
@@ -3008,10 +3033,11 @@ class LanguageUtil {
3008
3033
  const lngOnly = this.getLanguagePartFromCode(code);
3009
3034
  if (this.isSupportedCode(lngOnly)) return found = lngOnly;
3010
3035
  found = this.options.supportedLngs.find(supportedLng => {
3011
- if (supportedLng === lngOnly) return supportedLng;
3012
- if (supportedLng.indexOf('-') < 0 && lngOnly.indexOf('-') < 0) return;
3013
- if (supportedLng.indexOf('-') > 0 && lngOnly.indexOf('-') < 0 && supportedLng.substring(0, supportedLng.indexOf('-')) === lngOnly) return supportedLng;
3014
- if (supportedLng.indexOf(lngOnly) === 0 && lngOnly.length > 1) return supportedLng;
3036
+ if (supportedLng === lngOnly) return true;
3037
+ if (!supportedLng.includes('-') && !lngOnly.includes('-')) return false;
3038
+ if (supportedLng.includes('-') && !lngOnly.includes('-') && supportedLng.slice(0, supportedLng.indexOf('-')) === lngOnly) return true;
3039
+ if (supportedLng.startsWith(lngOnly) && lngOnly.length > 1) return true;
3040
+ return false;
3015
3041
  });
3016
3042
  });
3017
3043
  }
@@ -3042,7 +3068,7 @@ class LanguageUtil {
3042
3068
  this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
3043
3069
  }
3044
3070
  };
3045
- if (isString(code) && (code.indexOf('-') > -1 || code.indexOf('_') > -1)) {
3071
+ if (isString(code) && (code.includes('-') || code.includes('_'))) {
3046
3072
  if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code));
3047
3073
  if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code));
3048
3074
  if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code));
@@ -3050,7 +3076,7 @@ class LanguageUtil {
3050
3076
  addCode(this.formatLanguageCode(code));
3051
3077
  }
3052
3078
  fallbackCodes.forEach(fc => {
3053
- if (codes.indexOf(fc) < 0) addCode(this.formatLanguageCode(fc));
3079
+ if (!codes.includes(fc)) addCode(this.formatLanguageCode(fc));
3054
3080
  });
3055
3081
  return codes;
3056
3082
  }
@@ -3206,7 +3232,7 @@ class Interpolator {
3206
3232
  let replaces;
3207
3233
  const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
3208
3234
  const handleFormat = key => {
3209
- if (key.indexOf(this.formatSeparator) < 0) {
3235
+ if (!key.includes(this.formatSeparator)) {
3210
3236
  const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
3211
3237
  return this.alwaysFormat ? this.format(path, undefined, lng, {
3212
3238
  ...options,
@@ -3276,7 +3302,7 @@ class Interpolator {
3276
3302
  let clonedOptions;
3277
3303
  const handleHasOptions = (key, inheritedOptions) => {
3278
3304
  const sep = this.nestingOptionsSeparator;
3279
- if (key.indexOf(sep) < 0) return key;
3305
+ if (!key.includes(sep)) return key;
3280
3306
  const c = key.split(new RegExp(`${regexEscape(sep)}[ ]*{`));
3281
3307
  let optionsString = `{${c[1]}`;
3282
3308
  key = c[0];
@@ -3296,7 +3322,7 @@ class Interpolator {
3296
3322
  this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
3297
3323
  return `${key}${sep}${optionsString}`;
3298
3324
  }
3299
- if (clonedOptions.defaultValue && clonedOptions.defaultValue.indexOf(this.prefix) > -1) delete clonedOptions.defaultValue;
3325
+ if (clonedOptions.defaultValue && clonedOptions.defaultValue.includes(this.prefix)) delete clonedOptions.defaultValue;
3300
3326
  return key;
3301
3327
  };
3302
3328
  while (match = this.nestingRegexp.exec(str)) {
@@ -3335,13 +3361,13 @@ class Interpolator {
3335
3361
  const parseFormatStr = formatStr => {
3336
3362
  let formatName = formatStr.toLowerCase().trim();
3337
3363
  const formatOptions = {};
3338
- if (formatStr.indexOf('(') > -1) {
3364
+ if (formatStr.includes('(')) {
3339
3365
  const p = formatStr.split('(');
3340
3366
  formatName = p[0].toLowerCase().trim();
3341
- const optStr = p[1].substring(0, p[1].length - 1);
3342
- if (formatName === 'currency' && optStr.indexOf(':') < 0) {
3367
+ const optStr = p[1].slice(0, -1);
3368
+ if (formatName === 'currency' && !optStr.includes(':')) {
3343
3369
  if (!formatOptions.currency) formatOptions.currency = optStr.trim();
3344
- } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
3370
+ } else if (formatName === 'relativetime' && !optStr.includes(':')) {
3345
3371
  if (!formatOptions.range) formatOptions.range = optStr.trim();
3346
3372
  } else {
3347
3373
  const opts = optStr.split(';');
@@ -3435,9 +3461,11 @@ class Formatter {
3435
3461
  this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
3436
3462
  }
3437
3463
  format(value, format, lng, options = {}) {
3464
+ if (!format) return value;
3465
+ if (value == null) return value;
3438
3466
  const formats = format.split(this.formatSeparator);
3439
- if (formats.length > 1 && formats[0].indexOf('(') > 1 && formats[0].indexOf(')') < 0 && formats.find(f => f.indexOf(')') > -1)) {
3440
- const lastIndex = formats.findIndex(f => f.indexOf(')') > -1);
3467
+ if (formats.length > 1 && formats[0].indexOf('(') > 1 && !formats[0].includes(')') && formats.find(f => f.includes(')'))) {
3468
+ const lastIndex = formats.findIndex(f => f.includes(')'));
3441
3469
  formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
3442
3470
  }
3443
3471
  const result = formats.reduce((mem, f) => {
@@ -3591,7 +3619,7 @@ class Connector extends EventEmitter {
3591
3619
  }
3592
3620
  if (err && data && tried < this.maxRetries) {
3593
3621
  setTimeout(() => {
3594
- this.read.call(this, lng, ns, fcName, tried + 1, wait * 2, callback);
3622
+ this.read(lng, ns, fcName, tried + 1, wait * 2, callback);
3595
3623
  }, wait);
3596
3624
  return;
3597
3625
  }
@@ -3695,7 +3723,6 @@ const get = () => ({
3695
3723
  nonExplicitSupportedLngs: false,
3696
3724
  load: 'all',
3697
3725
  preload: false,
3698
- simplifyPluralSuffix: true,
3699
3726
  keySeparator: '.',
3700
3727
  nsSeparator: ':',
3701
3728
  pluralSeparator: '_',
@@ -3732,7 +3759,6 @@ const get = () => ({
3732
3759
  },
3733
3760
  interpolation: {
3734
3761
  escapeValue: true,
3735
- format: value => value,
3736
3762
  prefix: '{{',
3737
3763
  suffix: '}}',
3738
3764
  formatSeparator: ',',
@@ -3749,10 +3775,9 @@ const transformOptions = options => {
3749
3775
  if (isString(options.ns)) options.ns = [options.ns];
3750
3776
  if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
3751
3777
  if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
3752
- if (options.supportedLngs?.indexOf?.('cimode') < 0) {
3778
+ if (options.supportedLngs && !options.supportedLngs.includes('cimode')) {
3753
3779
  options.supportedLngs = options.supportedLngs.concat(['cimode']);
3754
3780
  }
3755
- if (typeof options.initImmediate === 'boolean') options.initAsync = options.initImmediate;
3756
3781
  return options;
3757
3782
  };
3758
3783
 
@@ -3765,23 +3790,6 @@ const bindMemberFunctions = inst => {
3765
3790
  }
3766
3791
  });
3767
3792
  };
3768
- const SUPPORT_NOTICE_KEY = '__i18next_supportNoticeShown';
3769
- const getSupportNoticeShown = () => typeof globalThis !== 'undefined' && !!globalThis[SUPPORT_NOTICE_KEY];
3770
- const setSupportNoticeShown = () => {
3771
- if (typeof globalThis !== 'undefined') globalThis[SUPPORT_NOTICE_KEY] = true;
3772
- };
3773
- const usesLocize = inst => {
3774
- if (inst?.modules?.backend?.name?.indexOf('Locize') > 0) return true;
3775
- if (inst?.modules?.backend?.constructor?.name?.indexOf('Locize') > 0) return true;
3776
- if (inst?.options?.backend?.backends) {
3777
- if (inst.options.backend.backends.some(b => b?.name?.indexOf('Locize') > 0 || b?.constructor?.name?.indexOf('Locize') > 0)) return true;
3778
- }
3779
- if (inst?.options?.backend?.projectId) return true;
3780
- if (inst?.options?.backend?.backendOptions) {
3781
- if (inst.options.backend.backendOptions.some(b => b?.projectId)) return true;
3782
- }
3783
- return false;
3784
- };
3785
3793
  class I18n extends EventEmitter {
3786
3794
  constructor(options = {}, callback) {
3787
3795
  super();
@@ -3811,7 +3819,7 @@ class I18n extends EventEmitter {
3811
3819
  if (options.defaultNS == null && options.ns) {
3812
3820
  if (isString(options.ns)) {
3813
3821
  options.defaultNS = options.ns;
3814
- } else if (options.ns.indexOf('translation') < 0) {
3822
+ } else if (!options.ns.includes('translation')) {
3815
3823
  options.defaultNS = options.ns[0];
3816
3824
  }
3817
3825
  }
@@ -3834,10 +3842,6 @@ class I18n extends EventEmitter {
3834
3842
  if (typeof this.options.overloadTranslationOptionHandler !== 'function') {
3835
3843
  this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
3836
3844
  }
3837
- if (this.options.showSupportNotice !== false && !usesLocize(this) && !getSupportNoticeShown()) {
3838
- 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 💙');
3839
- setSupportNoticeShown();
3840
- }
3841
3845
  const createClassOnDemand = ClassOrObject => {
3842
3846
  if (!ClassOrObject) return null;
3843
3847
  if (typeof ClassOrObject === 'function') return new ClassOrObject();
@@ -3862,14 +3866,9 @@ class I18n extends EventEmitter {
3862
3866
  s.resourceStore = this.store;
3863
3867
  s.languageUtils = lu;
3864
3868
  s.pluralResolver = new PluralResolver(lu, {
3865
- prepend: this.options.pluralSeparator,
3866
- simplifyPluralSuffix: this.options.simplifyPluralSuffix
3869
+ prepend: this.options.pluralSeparator
3867
3870
  });
3868
- const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
3869
- if (usingLegacyFormatFunction) {
3870
- this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
3871
- }
3872
- if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
3871
+ if (formatter) {
3873
3872
  s.formatter = createClassOnDemand(formatter);
3874
3873
  if (s.formatter.init) s.formatter.init(s, this.options);
3875
3874
  this.options.interpolation.format = s.formatter.format.bind(s.formatter);
@@ -3952,7 +3951,7 @@ class I18n extends EventEmitter {
3952
3951
  const lngs = this.services.languageUtils.toResolveHierarchy(lng);
3953
3952
  lngs.forEach(l => {
3954
3953
  if (l === 'cimode') return;
3955
- if (toLoad.indexOf(l) < 0) toLoad.push(l);
3954
+ if (!toLoad.includes(l)) toLoad.push(l);
3956
3955
  });
3957
3956
  };
3958
3957
  if (!usedLng) {
@@ -4017,16 +4016,16 @@ class I18n extends EventEmitter {
4017
4016
  }
4018
4017
  setResolvedLanguage(l) {
4019
4018
  if (!l || !this.languages) return;
4020
- if (['cimode', 'dev'].indexOf(l) > -1) return;
4019
+ if (['cimode', 'dev'].includes(l)) return;
4021
4020
  for (let li = 0; li < this.languages.length; li++) {
4022
4021
  const lngInLngs = this.languages[li];
4023
- if (['cimode', 'dev'].indexOf(lngInLngs) > -1) continue;
4022
+ if (['cimode', 'dev'].includes(lngInLngs)) continue;
4024
4023
  if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
4025
4024
  this.resolvedLanguage = lngInLngs;
4026
4025
  break;
4027
4026
  }
4028
4027
  }
4029
- if (!this.resolvedLanguage && this.languages.indexOf(l) < 0 && this.store.hasLanguageSomeTranslations(l)) {
4028
+ if (!this.resolvedLanguage && !this.languages.includes(l) && this.store.hasLanguageSomeTranslations(l)) {
4030
4029
  this.resolvedLanguage = l;
4031
4030
  this.languages.unshift(l);
4032
4031
  }
@@ -4098,21 +4097,20 @@ class I18n extends EventEmitter {
4098
4097
  o.lngs = o.lngs || fixedT.lngs;
4099
4098
  o.ns = o.ns || fixedT.ns;
4100
4099
  if (o.keyPrefix !== '') o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
4100
+ const selectorOpts = {
4101
+ ...this.options,
4102
+ ...o
4103
+ };
4104
+ if (typeof o.keyPrefix === 'function') o.keyPrefix = keysFromSelector(o.keyPrefix, selectorOpts);
4101
4105
  const keySeparator = this.options.keySeparator || '.';
4102
4106
  let resultKey;
4103
4107
  if (o.keyPrefix && Array.isArray(key)) {
4104
4108
  resultKey = key.map(k => {
4105
- if (typeof k === 'function') k = keysFromSelector(k, {
4106
- ...this.options,
4107
- ...opts
4108
- });
4109
+ if (typeof k === 'function') k = keysFromSelector(k, selectorOpts);
4109
4110
  return `${o.keyPrefix}${keySeparator}${k}`;
4110
4111
  });
4111
4112
  } else {
4112
- if (typeof key === 'function') key = keysFromSelector(key, {
4113
- ...this.options,
4114
- ...opts
4115
- });
4113
+ if (typeof key === 'function') key = keysFromSelector(key, selectorOpts);
4116
4114
  resultKey = o.keyPrefix ? `${o.keyPrefix}${keySeparator}${key}` : key;
4117
4115
  }
4118
4116
  return this.t(resultKey, o);
@@ -4169,7 +4167,7 @@ class I18n extends EventEmitter {
4169
4167
  }
4170
4168
  if (isString(ns)) ns = [ns];
4171
4169
  ns.forEach(n => {
4172
- if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
4170
+ if (!this.options.ns.includes(n)) this.options.ns.push(n);
4173
4171
  });
4174
4172
  this.loadResources(err => {
4175
4173
  deferred.resolve();
@@ -4181,7 +4179,7 @@ class I18n extends EventEmitter {
4181
4179
  const deferred = defer();
4182
4180
  if (isString(lngs)) lngs = [lngs];
4183
4181
  const preloaded = this.options.preload || [];
4184
- const newLngs = lngs.filter(lng => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
4182
+ const newLngs = lngs.filter(lng => !preloaded.includes(lng) && this.services.languageUtils.isSupportedCode(lng));
4185
4183
  if (!newLngs.length) {
4186
4184
  if (callback) callback();
4187
4185
  return Promise.resolve();
@@ -4206,7 +4204,7 @@ class I18n extends EventEmitter {
4206
4204
  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'];
4207
4205
  const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
4208
4206
  if (lng.toLowerCase().indexOf('-latn') > 1) return 'ltr';
4209
- return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
4207
+ return rtlLngs.includes(languageUtils.getLanguagePartFromCode(lng)) || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
4210
4208
  }
4211
4209
  static createInstance(options = {}, callback) {
4212
4210
  const instance = new I18n(options, callback);