@qping/plugin-bus 0.5.0 → 0.8.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/i18n.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // ../node_modules/i18next/dist/esm/i18next.js
1
+ // node_modules/i18next/dist/esm/i18next.js
2
2
  var isString = (obj) => typeof obj === "string";
3
3
  var defer = () => {
4
4
  let res;
@@ -13,7 +13,7 @@ var defer = () => {
13
13
  };
14
14
  var makeString = (object) => {
15
15
  if (object == null) return "";
16
- return "" + object;
16
+ return String(object);
17
17
  };
18
18
  var copy = (a, s, t2) => {
19
19
  a.forEach((m) => {
@@ -21,7 +21,7 @@ var copy = (a, s, t2) => {
21
21
  });
22
22
  };
23
23
  var lastOfPathSeparatorRegExp = /###/g;
24
- var cleanKey = (key) => key && key.indexOf("###") > -1 ? key.replace(lastOfPathSeparatorRegExp, ".") : key;
24
+ var cleanKey = (key) => key && key.includes("###") ? key.replace(lastOfPathSeparatorRegExp, ".") : key;
25
25
  var canNotTraverseDeeper = (object) => !object || isString(object);
26
26
  var getLastOfPath = (object, path, Empty) => {
27
27
  const stack = !isString(path) ? path : path.split(".");
@@ -92,7 +92,7 @@ var getPathWithDefaults = (data, defaultData, key) => {
92
92
  var deepExtend = (target, source, overwrite) => {
93
93
  for (const prop in source) {
94
94
  if (prop !== "__proto__" && prop !== "constructor") {
95
- if (prop in target) {
95
+ if (Object.prototype.hasOwnProperty.call(target, prop)) {
96
96
  if (isString(target[prop]) || target[prop] instanceof String || isString(source[prop]) || source[prop] instanceof String) {
97
97
  if (overwrite) target[prop] = source[prop];
98
98
  } else {
@@ -145,7 +145,7 @@ var looksLikeObjectPathRegExpCache = new RegExpCache(20);
145
145
  var looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
146
146
  nsSeparator = nsSeparator || "";
147
147
  keySeparator = keySeparator || "";
148
- const possibleChars = chars.filter((c) => nsSeparator.indexOf(c) < 0 && keySeparator.indexOf(c) < 0);
148
+ const possibleChars = chars.filter((c) => !nsSeparator.includes(c) && !keySeparator.includes(c));
149
149
  if (possibleChars.length === 0) return true;
150
150
  const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map((c) => c === "?" ? "\\?" : c).join("|")})`);
151
151
  let matched = !r.test(key);
@@ -178,7 +178,7 @@ var deepFind = (obj, path, keySeparator = ".") => {
178
178
  nextPath += tokens[j];
179
179
  next = current[nextPath];
180
180
  if (next !== void 0) {
181
- if (["string", "number", "boolean"].indexOf(typeof next) > -1 && j < tokens.length - 1) {
181
+ if (["string", "number", "boolean"].includes(typeof next) && j < tokens.length - 1) {
182
182
  continue;
183
183
  }
184
184
  i += j - i + 1;
@@ -229,6 +229,7 @@ var Logger = class _Logger {
229
229
  }
230
230
  forward(args, lvl, prefix, debugOnly) {
231
231
  if (debugOnly && !this.debug) return null;
232
+ args = args.map((a) => isString(a) ? a.replace(/[\r\n\x00-\x1F\x7F]/g, " ") : a);
232
233
  if (isString(args[0])) args[0] = `${prefix}${this.prefix} ${args[0]}`;
233
234
  return this.logger[lvl](args);
234
235
  }
@@ -267,6 +268,14 @@ var EventEmitter = class {
267
268
  }
268
269
  this.observers[event].delete(listener);
269
270
  }
271
+ once(event, listener) {
272
+ const wrapper = (...args) => {
273
+ listener(...args);
274
+ this.off(event, wrapper);
275
+ };
276
+ this.on(event, wrapper);
277
+ return this;
278
+ }
270
279
  emit(event, ...args) {
271
280
  if (this.observers[event]) {
272
281
  const cloned = Array.from(this.observers[event].entries());
@@ -280,7 +289,7 @@ var EventEmitter = class {
280
289
  const cloned = Array.from(this.observers["*"].entries());
281
290
  cloned.forEach(([observer, numTimesAdded]) => {
282
291
  for (let i = 0; i < numTimesAdded; i++) {
283
- observer.apply(observer, [event, ...args]);
292
+ observer(event, ...args);
284
293
  }
285
294
  });
286
295
  }
@@ -302,7 +311,7 @@ var ResourceStore = class extends EventEmitter {
302
311
  }
303
312
  }
304
313
  addNamespaces(ns) {
305
- if (this.options.ns.indexOf(ns) < 0) {
314
+ if (!this.options.ns.includes(ns)) {
306
315
  this.options.ns.push(ns);
307
316
  }
308
317
  }
@@ -316,7 +325,7 @@ var ResourceStore = class extends EventEmitter {
316
325
  const keySeparator = options.keySeparator !== void 0 ? options.keySeparator : this.options.keySeparator;
317
326
  const ignoreJSONStructure = options.ignoreJSONStructure !== void 0 ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
318
327
  let path;
319
- if (lng.indexOf(".") > -1) {
328
+ if (lng.includes(".")) {
320
329
  path = lng.split(".");
321
330
  } else {
322
331
  path = [lng, ns];
@@ -331,7 +340,7 @@ var ResourceStore = class extends EventEmitter {
331
340
  }
332
341
  }
333
342
  const result = getPath(this.data, path);
334
- if (!result && !ns && !key && lng.indexOf(".") > -1) {
343
+ if (!result && !ns && !key && lng.includes(".")) {
335
344
  lng = path[0];
336
345
  ns = path[1];
337
346
  key = path.slice(2).join(".");
@@ -345,7 +354,7 @@ var ResourceStore = class extends EventEmitter {
345
354
  const keySeparator = options.keySeparator !== void 0 ? options.keySeparator : this.options.keySeparator;
346
355
  let path = [lng, ns];
347
356
  if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
348
- if (lng.indexOf(".") > -1) {
357
+ if (lng.includes(".")) {
349
358
  path = lng.split(".");
350
359
  value = ns;
351
360
  ns = path[1];
@@ -369,7 +378,7 @@ var ResourceStore = class extends EventEmitter {
369
378
  skipCopy: false
370
379
  }) {
371
380
  let path = [lng, ns];
372
- if (lng.indexOf(".") > -1) {
381
+ if (lng.includes(".")) {
373
382
  path = lng.split(".");
374
383
  deep = resources;
375
384
  resources = ns;
@@ -447,16 +456,19 @@ function keysFromSelector(selector, opts) {
447
456
  } = selector(createProxy());
448
457
  const keySeparator = opts?.keySeparator ?? ".";
449
458
  const nsSeparator = opts?.nsSeparator ?? ":";
459
+ const strict = opts?.enableSelector === "strict";
450
460
  if (path.length > 1 && nsSeparator) {
451
461
  const ns = opts?.ns;
452
- const nsArray = Array.isArray(ns) ? ns : null;
453
- if (nsArray && nsArray.length > 1 && nsArray.slice(1).includes(path[0])) {
454
- return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
462
+ const nsList = strict ? Array.isArray(ns) ? ns : ns ? [ns] : null : Array.isArray(ns) ? ns : null;
463
+ if (nsList) {
464
+ const candidates = strict ? nsList : nsList.length > 1 ? nsList.slice(1) : [];
465
+ if (candidates.includes(path[0])) {
466
+ return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
467
+ }
455
468
  }
456
469
  }
457
470
  return path.join(keySeparator);
458
471
  }
459
- var checkedLoadedFor = {};
460
472
  var shouldHandleAsObject = (res) => !isString(res) && typeof res !== "boolean" && typeof res !== "number";
461
473
  var Translator = class _Translator extends EventEmitter {
462
474
  constructor(services, options = {}) {
@@ -467,6 +479,7 @@ var Translator = class _Translator extends EventEmitter {
467
479
  this.options.keySeparator = ".";
468
480
  }
469
481
  this.logger = baseLogger.create("translator");
482
+ this.checkedLoadedFor = {};
470
483
  }
471
484
  changeLanguage(lng) {
472
485
  if (lng) this.language = lng;
@@ -491,7 +504,7 @@ var Translator = class _Translator extends EventEmitter {
491
504
  if (nsSeparator === void 0) nsSeparator = ":";
492
505
  const keySeparator = opt.keySeparator !== void 0 ? opt.keySeparator : this.options.keySeparator;
493
506
  let namespaces = opt.ns || this.options.defaultNS || [];
494
- const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1;
507
+ const wouldCheckForNsInKey = nsSeparator && key.includes(nsSeparator);
495
508
  const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !opt.keySeparator && !this.options.userDefinedNsSeparator && !opt.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
496
509
  if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
497
510
  const m = key.match(this.interpolator.nestingRegexp);
@@ -502,7 +515,7 @@ var Translator = class _Translator extends EventEmitter {
502
515
  };
503
516
  }
504
517
  const parts = key.split(nsSeparator);
505
- if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
518
+ if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.includes(parts[0])) namespaces = parts.shift();
506
519
  key = parts.join(keySeparator);
507
520
  }
508
521
  return {
@@ -589,7 +602,7 @@ var Translator = class _Translator extends EventEmitter {
589
602
  }
590
603
  const handleAsObject = shouldHandleAsObject(resForObjHndl);
591
604
  const resType = Object.prototype.toString.apply(resForObjHndl);
592
- if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
605
+ if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && !noObject.includes(resType) && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
593
606
  if (!opt.returnObjects && !this.options.returnObjects) {
594
607
  if (!this.options.returnedObjectHandler) {
595
608
  this.logger.warn("accessing an object - but returnObjects options is not enabled!");
@@ -653,7 +666,7 @@ var Translator = class _Translator extends EventEmitter {
653
666
  const resForMissing = missingKeyNoValueFallbackToKey && usedKey ? void 0 : res;
654
667
  const updateMissing = hasDefaultValue && defaultValue !== res && this.options.updateMissing;
655
668
  if (usedKey || usedDefault || updateMissing) {
656
- this.logger.log(updateMissing ? "updateKey" : "missingKey", lng, namespace, key, updateMissing ? defaultValue : res);
669
+ this.logger.log(updateMissing ? "updateKey" : "missingKey", lng, namespace, needsPluralHandling && !updateMissing ? `${key}${this.pluralResolver.getSuffix(lng, opt.count, opt)}` : key, updateMissing ? defaultValue : res);
657
670
  if (keySeparator) {
658
671
  const fk = this.resolve(key, {
659
672
  ...opt,
@@ -685,7 +698,7 @@ var Translator = class _Translator extends EventEmitter {
685
698
  if (this.options.saveMissingPlurals && needsPluralHandling) {
686
699
  lngs.forEach((language) => {
687
700
  const suffixes = this.pluralResolver.getSuffixes(language, opt);
688
- if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) {
701
+ if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && !suffixes.includes(`${this.options.pluralSeparator}zero`)) {
689
702
  suffixes.push(`${this.options.pluralSeparator}zero`);
690
703
  }
691
704
  suffixes.forEach((suffix) => {
@@ -795,8 +808,8 @@ var Translator = class _Translator extends EventEmitter {
795
808
  namespaces.forEach((ns) => {
796
809
  if (this.isValidLookup(found)) return;
797
810
  usedNS = ns;
798
- if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
799
- checkedLoadedFor[`${codes[0]}-${ns}`] = true;
811
+ if (!this.checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
812
+ this.checkedLoadedFor[`${codes[0]}-${ns}`] = true;
800
813
  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!!!");
801
814
  }
802
815
  codes.forEach((code) => {
@@ -811,7 +824,7 @@ var Translator = class _Translator extends EventEmitter {
811
824
  const zeroSuffix = `${this.options.pluralSeparator}zero`;
812
825
  const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
813
826
  if (needsPluralHandling) {
814
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
827
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
815
828
  finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
816
829
  }
817
830
  finalKeys.push(key + pluralSuffix);
@@ -823,7 +836,7 @@ var Translator = class _Translator extends EventEmitter {
823
836
  const contextKey = `${key}${this.options.contextSeparator || "_"}${opt.context}`;
824
837
  finalKeys.push(contextKey);
825
838
  if (needsPluralHandling) {
826
- if (opt.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
839
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
827
840
  finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
828
841
  }
829
842
  finalKeys.push(contextKey + pluralSuffix);
@@ -863,7 +876,10 @@ var Translator = class _Translator extends EventEmitter {
863
876
  const useOptionsReplaceForData = options.replace && !isString(options.replace);
864
877
  let data = useOptionsReplaceForData ? options.replace : options;
865
878
  if (useOptionsReplaceForData && typeof options.count !== "undefined") {
866
- data.count = options.count;
879
+ data = {
880
+ ...data,
881
+ count: options.count
882
+ };
867
883
  }
868
884
  if (this.options.interpolation.defaultVariables) {
869
885
  data = {
@@ -884,7 +900,7 @@ var Translator = class _Translator extends EventEmitter {
884
900
  static hasDefaultValue(options) {
885
901
  const prefix = "defaultValue";
886
902
  for (const option in options) {
887
- if (Object.prototype.hasOwnProperty.call(options, option) && prefix === option.substring(0, prefix.length) && void 0 !== options[option]) {
903
+ if (Object.prototype.hasOwnProperty.call(options, option) && option.startsWith(prefix) && void 0 !== options[option]) {
888
904
  return true;
889
905
  }
890
906
  }
@@ -896,10 +912,14 @@ var LanguageUtil = class {
896
912
  this.options = options;
897
913
  this.supportedLngs = this.options.supportedLngs || false;
898
914
  this.logger = baseLogger.create("languageUtils");
915
+ this.resolveHierarchyCache = {};
916
+ }
917
+ clearCache() {
918
+ this.resolveHierarchyCache = {};
899
919
  }
900
920
  getScriptPartFromCode(code) {
901
921
  code = getCleanedCode(code);
902
- if (!code || code.indexOf("-") < 0) return null;
922
+ if (!code || !code.includes("-")) return null;
903
923
  const p = code.split("-");
904
924
  if (p.length === 2) return null;
905
925
  p.pop();
@@ -908,12 +928,12 @@ var LanguageUtil = class {
908
928
  }
909
929
  getLanguagePartFromCode(code) {
910
930
  code = getCleanedCode(code);
911
- if (!code || code.indexOf("-") < 0) return code;
931
+ if (!code || !code.includes("-")) return code;
912
932
  const p = code.split("-");
913
933
  return this.formatLanguageCode(p[0]);
914
934
  }
915
935
  formatLanguageCode(code) {
916
- if (isString(code) && code.indexOf("-") > -1) {
936
+ if (isString(code) && code.includes("-")) {
917
937
  let formattedCode;
918
938
  try {
919
939
  formattedCode = Intl.getCanonicalLocales(code)[0];
@@ -934,7 +954,7 @@ var LanguageUtil = class {
934
954
  if (this.options.load === "languageOnly" || this.options.nonExplicitSupportedLngs) {
935
955
  code = this.getLanguagePartFromCode(code);
936
956
  }
937
- return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1;
957
+ return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.includes(code);
938
958
  }
939
959
  getBestMatchFromCodes(codes) {
940
960
  if (!codes) return null;
@@ -952,10 +972,11 @@ var LanguageUtil = class {
952
972
  const lngOnly = this.getLanguagePartFromCode(code);
953
973
  if (this.isSupportedCode(lngOnly)) return found = lngOnly;
954
974
  found = this.options.supportedLngs.find((supportedLng) => {
955
- if (supportedLng === lngOnly) return supportedLng;
956
- if (supportedLng.indexOf("-") < 0 && lngOnly.indexOf("-") < 0) return;
957
- if (supportedLng.indexOf("-") > 0 && lngOnly.indexOf("-") < 0 && supportedLng.substring(0, supportedLng.indexOf("-")) === lngOnly) return supportedLng;
958
- if (supportedLng.indexOf(lngOnly) === 0 && lngOnly.length > 1) return supportedLng;
975
+ if (supportedLng === lngOnly) return true;
976
+ if (!supportedLng.includes("-") && !lngOnly.includes("-")) return false;
977
+ if (supportedLng.includes("-") && !lngOnly.includes("-") && supportedLng.slice(0, supportedLng.indexOf("-")) === lngOnly) return true;
978
+ if (supportedLng.startsWith(lngOnly) && lngOnly.length > 1) return true;
979
+ return false;
959
980
  });
960
981
  });
961
982
  }
@@ -976,6 +997,27 @@ var LanguageUtil = class {
976
997
  return found || [];
977
998
  }
978
999
  toResolveHierarchy(code, fallbackCode) {
1000
+ const fallbackLng = this.options.fallbackLng;
1001
+ const fallbackLngKey = Array.isArray(fallbackLng) ? fallbackLng.join("|") : fallbackLng;
1002
+ if (fallbackLngKey !== this._cachedFallbackLng) {
1003
+ this.resolveHierarchyCache = {};
1004
+ this._cachedFallbackLng = fallbackLngKey;
1005
+ }
1006
+ const hasCacheableFallback = fallbackCode === void 0 || fallbackCode === false || isString(fallbackCode);
1007
+ const usesUncacheableOptionsFallback = fallbackCode === void 0 && typeof this.options.fallbackLng === "function";
1008
+ const cacheable = isString(code) && hasCacheableFallback && !usesUncacheableOptionsFallback;
1009
+ let cacheKey = null;
1010
+ if (cacheable) {
1011
+ let fallbackCacheKey;
1012
+ if (fallbackCode === void 0) fallbackCacheKey = "undefined";
1013
+ else if (fallbackCode === false) fallbackCacheKey = "boolean:false";
1014
+ else fallbackCacheKey = `string:${fallbackCode}`;
1015
+ cacheKey = `${code.length}:${code}|${fallbackCacheKey}`;
1016
+ }
1017
+ if (cacheKey !== null) {
1018
+ const cached = this.resolveHierarchyCache[cacheKey];
1019
+ if (cached !== void 0) return cached.slice();
1020
+ }
979
1021
  const fallbackCodes = this.getFallbackCodes((fallbackCode === false ? [] : fallbackCode) || this.options.fallbackLng || [], code);
980
1022
  const codes = [];
981
1023
  const addCode = (c) => {
@@ -986,7 +1028,7 @@ var LanguageUtil = class {
986
1028
  this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
987
1029
  }
988
1030
  };
989
- if (isString(code) && (code.indexOf("-") > -1 || code.indexOf("_") > -1)) {
1031
+ if (isString(code) && (code.includes("-") || code.includes("_"))) {
990
1032
  if (this.options.load !== "languageOnly") addCode(this.formatLanguageCode(code));
991
1033
  if (this.options.load !== "languageOnly" && this.options.load !== "currentOnly") addCode(this.getScriptPartFromCode(code));
992
1034
  if (this.options.load !== "currentOnly") addCode(this.getLanguagePartFromCode(code));
@@ -994,8 +1036,12 @@ var LanguageUtil = class {
994
1036
  addCode(this.formatLanguageCode(code));
995
1037
  }
996
1038
  fallbackCodes.forEach((fc) => {
997
- if (codes.indexOf(fc) < 0) addCode(this.formatLanguageCode(fc));
1039
+ if (!codes.includes(fc)) addCode(this.formatLanguageCode(fc));
998
1040
  });
1041
+ if (cacheKey !== null) {
1042
+ this.resolveHierarchyCache[cacheKey] = codes;
1043
+ return codes.slice();
1044
+ }
999
1045
  return codes;
1000
1046
  }
1001
1047
  };
@@ -1118,8 +1164,8 @@ var Interpolator = class {
1118
1164
  this.prefix = prefix ? regexEscape(prefix) : prefixEscaped || "{{";
1119
1165
  this.suffix = suffix ? regexEscape(suffix) : suffixEscaped || "}}";
1120
1166
  this.formatSeparator = formatSeparator || ",";
1121
- this.unescapePrefix = unescapeSuffix ? "" : unescapePrefix || "-";
1122
- this.unescapeSuffix = this.unescapePrefix ? "" : unescapeSuffix || "";
1167
+ this.unescapePrefix = unescapeSuffix ? "" : unescapePrefix ? regexEscape(unescapePrefix) : "-";
1168
+ this.unescapeSuffix = this.unescapePrefix ? "" : unescapeSuffix ? regexEscape(unescapeSuffix) : "";
1123
1169
  this.nestingPrefix = nestingPrefix ? regexEscape(nestingPrefix) : nestingPrefixEscaped || regexEscape("$t(");
1124
1170
  this.nestingSuffix = nestingSuffix ? regexEscape(nestingSuffix) : nestingSuffixEscaped || regexEscape(")");
1125
1171
  this.nestingOptionsSeparator = nestingOptionsSeparator || ",";
@@ -1148,7 +1194,7 @@ var Interpolator = class {
1148
1194
  let replaces;
1149
1195
  const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
1150
1196
  const handleFormat = (key) => {
1151
- if (key.indexOf(this.formatSeparator) < 0) {
1197
+ if (!key.includes(this.formatSeparator)) {
1152
1198
  const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
1153
1199
  return this.alwaysFormat ? this.format(path, void 0, lng, {
1154
1200
  ...options,
@@ -1166,14 +1212,17 @@ var Interpolator = class {
1166
1212
  });
1167
1213
  };
1168
1214
  this.resetRegExp();
1215
+ if (!this.escapeValue && typeof str === "string" && /\$t\([^)]*\{[^}]*\{\{/.test(str)) {
1216
+ this.logger.warn("nesting options string contains interpolated variables with escapeValue: false \u2014 if any of those values are attacker-controlled they can inject additional nesting options (e.g. redirect lng/ns). Sanitise untrusted input before passing it to t(), or keep escapeValue: true.");
1217
+ }
1169
1218
  const missingInterpolationHandler = options?.missingInterpolationHandler || this.options.missingInterpolationHandler;
1170
1219
  const skipOnVariables = options?.interpolation?.skipOnVariables !== void 0 ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
1171
1220
  const todos = [{
1172
1221
  regex: this.regexpUnescape,
1173
- safeValue: (val) => regexSafe(val)
1222
+ safeValue: (val) => val
1174
1223
  }, {
1175
1224
  regex: this.regexp,
1176
- safeValue: (val) => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
1225
+ safeValue: (val) => this.escapeValue ? this.escape(val) : val
1177
1226
  }];
1178
1227
  todos.forEach((todo) => {
1179
1228
  replaces = 0;
@@ -1197,9 +1246,9 @@ var Interpolator = class {
1197
1246
  value = makeString(value);
1198
1247
  }
1199
1248
  const safeValue = todo.safeValue(value);
1200
- str = str.replace(match[0], safeValue);
1249
+ str = str.replace(match[0], regexSafe(safeValue));
1201
1250
  if (skipOnVariables) {
1202
- todo.regex.lastIndex += value.length;
1251
+ todo.regex.lastIndex += safeValue.length;
1203
1252
  todo.regex.lastIndex -= match[0].length;
1204
1253
  } else {
1205
1254
  todo.regex.lastIndex = 0;
@@ -1218,7 +1267,7 @@ var Interpolator = class {
1218
1267
  let clonedOptions;
1219
1268
  const handleHasOptions = (key, inheritedOptions) => {
1220
1269
  const sep = this.nestingOptionsSeparator;
1221
- if (key.indexOf(sep) < 0) return key;
1270
+ if (!key.includes(sep)) return key;
1222
1271
  const c = key.split(new RegExp(`${regexEscape(sep)}[ ]*{`));
1223
1272
  let optionsString = `{${c[1]}`;
1224
1273
  key = c[0];
@@ -1238,7 +1287,7 @@ var Interpolator = class {
1238
1287
  this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
1239
1288
  return `${key}${sep}${optionsString}`;
1240
1289
  }
1241
- if (clonedOptions.defaultValue && clonedOptions.defaultValue.indexOf(this.prefix) > -1) delete clonedOptions.defaultValue;
1290
+ if (clonedOptions.defaultValue && clonedOptions.defaultValue.includes(this.prefix)) delete clonedOptions.defaultValue;
1242
1291
  return key;
1243
1292
  };
1244
1293
  while (match = this.nestingRegexp.exec(str)) {
@@ -1249,7 +1298,7 @@ var Interpolator = class {
1249
1298
  clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
1250
1299
  clonedOptions.applyPostProcessor = false;
1251
1300
  delete clonedOptions.defaultValue;
1252
- const keyEndIndex = /{.*}/.test(match[1]) ? match[1].lastIndexOf("}") + 1 : match[1].indexOf(this.formatSeparator);
1301
+ const keyEndIndex = /{.*}/s.test(match[1]) ? match[1].lastIndexOf("}") + 1 : match[1].indexOf(this.formatSeparator);
1253
1302
  if (keyEndIndex !== -1) {
1254
1303
  formatters = match[1].slice(keyEndIndex).split(this.formatSeparator).map((elem) => elem.trim()).filter(Boolean);
1255
1304
  match[1] = match[1].slice(0, keyEndIndex);
@@ -1276,13 +1325,13 @@ var Interpolator = class {
1276
1325
  var parseFormatStr = (formatStr) => {
1277
1326
  let formatName = formatStr.toLowerCase().trim();
1278
1327
  const formatOptions = {};
1279
- if (formatStr.indexOf("(") > -1) {
1328
+ if (formatStr.includes("(")) {
1280
1329
  const p = formatStr.split("(");
1281
1330
  formatName = p[0].toLowerCase().trim();
1282
- const optStr = p[1].substring(0, p[1].length - 1);
1283
- if (formatName === "currency" && optStr.indexOf(":") < 0) {
1331
+ const optStr = p[1].slice(0, -1);
1332
+ if (formatName === "currency" && !optStr.includes(":")) {
1284
1333
  if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1285
- } else if (formatName === "relativetime" && optStr.indexOf(":") < 0) {
1334
+ } else if (formatName === "relativetime" && !optStr.includes(":")) {
1286
1335
  if (!formatOptions.range) formatOptions.range = optStr.trim();
1287
1336
  } else {
1288
1337
  const opts = optStr.split(";");
@@ -1376,10 +1425,16 @@ var Formatter = class {
1376
1425
  this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
1377
1426
  }
1378
1427
  format(value, format, lng, options = {}) {
1379
- const formats = format.split(this.formatSeparator);
1380
- if (formats.length > 1 && formats[0].indexOf("(") > 1 && formats[0].indexOf(")") < 0 && formats.find((f) => f.indexOf(")") > -1)) {
1381
- const lastIndex = formats.findIndex((f) => f.indexOf(")") > -1);
1382
- formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
1428
+ if (!format) return value;
1429
+ if (value == null) return value;
1430
+ const rawFormats = format.split(this.formatSeparator);
1431
+ const formats = [];
1432
+ for (let i = 0; i < rawFormats.length; i++) {
1433
+ let f = rawFormats[i];
1434
+ while (f.indexOf("(") > -1 && !f.includes(")") && i + 1 < rawFormats.length) {
1435
+ f = `${f}${this.formatSeparator}${rawFormats[++i]}`;
1436
+ }
1437
+ formats.push(f);
1383
1438
  }
1384
1439
  const result = formats.reduce((mem, f) => {
1385
1440
  const {
@@ -1532,7 +1587,7 @@ var Connector = class extends EventEmitter {
1532
1587
  }
1533
1588
  if (err && data && tried < this.maxRetries) {
1534
1589
  setTimeout(() => {
1535
- this.read.call(this, lng, ns, fcName, tried + 1, wait * 2, callback);
1590
+ this.read(lng, ns, fcName, tried + 1, wait * 2, callback);
1536
1591
  }, wait);
1537
1592
  return;
1538
1593
  }
@@ -1636,11 +1691,11 @@ var get = () => ({
1636
1691
  nonExplicitSupportedLngs: false,
1637
1692
  load: "all",
1638
1693
  preload: false,
1639
- simplifyPluralSuffix: true,
1640
1694
  keySeparator: ".",
1641
1695
  nsSeparator: ":",
1642
1696
  pluralSeparator: "_",
1643
1697
  contextSeparator: "_",
1698
+ enableSelector: false,
1644
1699
  partialBundledLanguages: false,
1645
1700
  saveMissing: false,
1646
1701
  updateMissing: false,
@@ -1673,7 +1728,6 @@ var get = () => ({
1673
1728
  },
1674
1729
  interpolation: {
1675
1730
  escapeValue: true,
1676
- format: (value) => value,
1677
1731
  prefix: "{{",
1678
1732
  suffix: "}}",
1679
1733
  formatSeparator: ",",
@@ -1690,10 +1744,9 @@ var transformOptions = (options) => {
1690
1744
  if (isString(options.ns)) options.ns = [options.ns];
1691
1745
  if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
1692
1746
  if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
1693
- if (options.supportedLngs?.indexOf?.("cimode") < 0) {
1747
+ if (options.supportedLngs && !options.supportedLngs.includes("cimode")) {
1694
1748
  options.supportedLngs = options.supportedLngs.concat(["cimode"]);
1695
1749
  }
1696
- if (typeof options.initImmediate === "boolean") options.initAsync = options.initImmediate;
1697
1750
  return options;
1698
1751
  };
1699
1752
  var noop = () => {
@@ -1706,28 +1759,6 @@ var bindMemberFunctions = (inst) => {
1706
1759
  }
1707
1760
  });
1708
1761
  };
1709
- var SUPPORT_NOTICE_KEY = "__i18next_supportNoticeShown";
1710
- var getSupportNoticeShown = () => {
1711
- if (typeof globalThis !== "undefined" && !!globalThis[SUPPORT_NOTICE_KEY]) return true;
1712
- if (typeof process !== "undefined" && process.env && process.env.I18NEXT_NO_SUPPORT_NOTICE) return true;
1713
- if (typeof process !== "undefined" && process.env && process.env.NODE_ENV === "production") return true;
1714
- return false;
1715
- };
1716
- var setSupportNoticeShown = () => {
1717
- if (typeof globalThis !== "undefined") globalThis[SUPPORT_NOTICE_KEY] = true;
1718
- };
1719
- var usesLocize = (inst) => {
1720
- if (inst?.modules?.backend?.name?.indexOf("Locize") > 0) return true;
1721
- if (inst?.modules?.backend?.constructor?.name?.indexOf("Locize") > 0) return true;
1722
- if (inst?.options?.backend?.backends) {
1723
- if (inst.options.backend.backends.some((b) => b?.name?.indexOf("Locize") > 0 || b?.constructor?.name?.indexOf("Locize") > 0)) return true;
1724
- }
1725
- if (inst?.options?.backend?.projectId) return true;
1726
- if (inst?.options?.backend?.backendOptions) {
1727
- if (inst.options.backend.backendOptions.some((b) => b?.projectId)) return true;
1728
- }
1729
- return false;
1730
- };
1731
1762
  var I18n = class _I18n extends EventEmitter {
1732
1763
  constructor(options = {}, callback) {
1733
1764
  super();
@@ -1757,7 +1788,7 @@ var I18n = class _I18n extends EventEmitter {
1757
1788
  if (options.defaultNS == null && options.ns) {
1758
1789
  if (isString(options.ns)) {
1759
1790
  options.defaultNS = options.ns;
1760
- } else if (options.ns.indexOf("translation") < 0) {
1791
+ } else if (!options.ns.includes("translation")) {
1761
1792
  options.defaultNS = options.ns[0];
1762
1793
  }
1763
1794
  }
@@ -1780,10 +1811,6 @@ var I18n = class _I18n extends EventEmitter {
1780
1811
  if (typeof this.options.overloadTranslationOptionHandler !== "function") {
1781
1812
  this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
1782
1813
  }
1783
- if (this.options.showSupportNotice !== false && !usesLocize(this) && !getSupportNoticeShown()) {
1784
- if (typeof console !== "undefined" && typeof console.info !== "undefined") console.info("\u{1F310} i18next is made possible by our own product, Locize \u2014 consider powering your project with managed localization (AI, CDN, integrations): https://locize.com \u{1F499}");
1785
- setSupportNoticeShown();
1786
- }
1787
1814
  const createClassOnDemand = (ClassOrObject) => {
1788
1815
  if (!ClassOrObject) return null;
1789
1816
  if (typeof ClassOrObject === "function") return new ClassOrObject();
@@ -1808,14 +1835,9 @@ var I18n = class _I18n extends EventEmitter {
1808
1835
  s.resourceStore = this.store;
1809
1836
  s.languageUtils = lu;
1810
1837
  s.pluralResolver = new PluralResolver(lu, {
1811
- prepend: this.options.pluralSeparator,
1812
- simplifyPluralSuffix: this.options.simplifyPluralSuffix
1838
+ prepend: this.options.pluralSeparator
1813
1839
  });
1814
- const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
1815
- if (usingLegacyFormatFunction) {
1816
- this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
1817
- }
1818
- if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
1840
+ if (formatter) {
1819
1841
  s.formatter = createClassOnDemand(formatter);
1820
1842
  if (s.formatter.init) s.formatter.init(s, this.options);
1821
1843
  this.options.interpolation.format = s.formatter.format.bind(s.formatter);
@@ -1875,7 +1897,7 @@ var I18n = class _I18n extends EventEmitter {
1875
1897
  deferred.resolve(t2);
1876
1898
  callback(err, t2);
1877
1899
  };
1878
- if (this.languages && !this.isInitialized) return finish(null, this.t.bind(this));
1900
+ if ((this.languages || this.isLanguageChangingTo) && !this.isInitialized) return finish(null, this.t.bind(this));
1879
1901
  this.changeLanguage(this.options.lng, finish);
1880
1902
  };
1881
1903
  if (this.options.resources || !this.options.initAsync) {
@@ -1898,7 +1920,7 @@ var I18n = class _I18n extends EventEmitter {
1898
1920
  const lngs = this.services.languageUtils.toResolveHierarchy(lng);
1899
1921
  lngs.forEach((l) => {
1900
1922
  if (l === "cimode") return;
1901
- if (toLoad.indexOf(l) < 0) toLoad.push(l);
1923
+ if (!toLoad.includes(l)) toLoad.push(l);
1902
1924
  });
1903
1925
  };
1904
1926
  if (!usedLng) {
@@ -1963,16 +1985,16 @@ var I18n = class _I18n extends EventEmitter {
1963
1985
  }
1964
1986
  setResolvedLanguage(l) {
1965
1987
  if (!l || !this.languages) return;
1966
- if (["cimode", "dev"].indexOf(l) > -1) return;
1988
+ if (["cimode", "dev"].includes(l)) return;
1967
1989
  for (let li = 0; li < this.languages.length; li++) {
1968
1990
  const lngInLngs = this.languages[li];
1969
- if (["cimode", "dev"].indexOf(lngInLngs) > -1) continue;
1991
+ if (["cimode", "dev"].includes(lngInLngs)) continue;
1970
1992
  if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
1971
1993
  this.resolvedLanguage = lngInLngs;
1972
1994
  break;
1973
1995
  }
1974
1996
  }
1975
- if (!this.resolvedLanguage && this.languages.indexOf(l) < 0 && this.store.hasLanguageSomeTranslations(l)) {
1997
+ if (!this.resolvedLanguage && !this.languages.includes(l) && this.store.hasLanguageSomeTranslations(l)) {
1976
1998
  this.resolvedLanguage = l;
1977
1999
  this.languages.unshift(l);
1978
2000
  }
@@ -2030,7 +2052,8 @@ var I18n = class _I18n extends EventEmitter {
2030
2052
  }
2031
2053
  return deferred;
2032
2054
  }
2033
- getFixedT(lng, ns, keyPrefix) {
2055
+ getFixedT(lng, ns, keyPrefix, fixedOpts) {
2056
+ const scopeNs = fixedOpts?.scopeNs;
2034
2057
  const fixedT = (key, opts, ...rest) => {
2035
2058
  let o;
2036
2059
  if (typeof opts !== "object") {
@@ -2042,12 +2065,14 @@ var I18n = class _I18n extends EventEmitter {
2042
2065
  }
2043
2066
  o.lng = o.lng || fixedT.lng;
2044
2067
  o.lngs = o.lngs || fixedT.lngs;
2068
+ const explicitCallNs = o.ns !== void 0 && o.ns !== null;
2045
2069
  o.ns = o.ns || fixedT.ns;
2046
2070
  if (o.keyPrefix !== "") o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
2047
2071
  const selectorOpts = {
2048
2072
  ...this.options,
2049
2073
  ...o
2050
2074
  };
2075
+ if (Array.isArray(scopeNs) && !explicitCallNs) selectorOpts.ns = scopeNs;
2051
2076
  if (typeof o.keyPrefix === "function") o.keyPrefix = keysFromSelector(o.keyPrefix, selectorOpts);
2052
2077
  const keySeparator = this.options.keySeparator || ".";
2053
2078
  let resultKey;
@@ -2114,7 +2139,7 @@ var I18n = class _I18n extends EventEmitter {
2114
2139
  }
2115
2140
  if (isString(ns)) ns = [ns];
2116
2141
  ns.forEach((n) => {
2117
- if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
2142
+ if (!this.options.ns.includes(n)) this.options.ns.push(n);
2118
2143
  });
2119
2144
  this.loadResources((err) => {
2120
2145
  deferred.resolve();
@@ -2126,7 +2151,7 @@ var I18n = class _I18n extends EventEmitter {
2126
2151
  const deferred = defer();
2127
2152
  if (isString(lngs)) lngs = [lngs];
2128
2153
  const preloaded = this.options.preload || [];
2129
- const newLngs = lngs.filter((lng) => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
2154
+ const newLngs = lngs.filter((lng) => !preloaded.includes(lng) && this.services.languageUtils.isSupportedCode(lng));
2130
2155
  if (!newLngs.length) {
2131
2156
  if (callback) callback();
2132
2157
  return Promise.resolve();
@@ -2152,7 +2177,7 @@ var I18n = class _I18n extends EventEmitter {
2152
2177
  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"];
2153
2178
  const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
2154
2179
  if (lng.toLowerCase().indexOf("-latn") > 1) return "ltr";
2155
- return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf("-arab") > 1 ? "rtl" : "ltr";
2180
+ return rtlLngs.includes(languageUtils.getLanguagePartFromCode(lng)) || lng.toLowerCase().indexOf("-arab") > 1 ? "rtl" : "ltr";
2156
2181
  }
2157
2182
  static createInstance(options = {}, callback) {
2158
2183
  const instance2 = new _I18n(options, callback);
@@ -2273,9 +2298,8 @@ var MyToolsI18n = class {
2273
2298
  void this.#instance.init({
2274
2299
  lng: this.#locale,
2275
2300
  fallbackLng: this.#fallbackLocale,
2276
- initImmediate: false,
2301
+ initAsync: false,
2277
2302
  debug: false,
2278
- showSupportNotice: false,
2279
2303
  keySeparator: false,
2280
2304
  nsSeparator: false,
2281
2305
  interpolation: { escapeValue: false },