• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

i18next / i18next / #11965

08 Jun 2023 07:01AM UTC coverage: 56.318% (-38.9%) from 95.213%
#11965

push

web-flow
Redesign `t` function types (#1911)

* Redesign t function types

* Add extra tests for t function and fix interpolation types

* Bump typescript version

574 of 1535 branches covered (37.39%)

517 of 918 relevant lines covered (56.32%)

24.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.54
/src/ResourceStore.js
1
import EventEmitter from './EventEmitter.js';
2
import * as utils from './utils.js';
3

32!
4
class ResourceStore extends EventEmitter {
1✔
5
  constructor(data, options = { ns: ['translation'], defaultNS: 'translation' }) {
6
    super();
7
    if (utils.isIE10) {
1✔
8
      EventEmitter.call(this); // <=IE10 fix (unable to call parent constructor)
1✔
9
    }
1✔
10

×
11
    this.data = data || {};
1!
12
    this.options = options;
1!
13
    if (this.options.keySeparator === undefined) {
×
14
      this.options.keySeparator = '.';
×
15
    }
×
16
    if (this.options.ignoreJSONStructure === undefined) {
8!
17
      this.options.ignoreJSONStructure = true;
12!
18
    }
1!
19
  }
12!
20

12!
21
  addNamespaces(ns) {
1!
22
    if (this.options.ns.indexOf(ns) < 0) {
1!
23
      this.options.ns.push(ns);
8!
24
    }
8!
25
  }
×
26

1!
27
  removeNamespaces(ns) {
1!
28
    const index = this.options.ns.indexOf(ns);
1✔
29
    if (index > -1) {
1✔
30
      this.options.ns.splice(index, 1);
1✔
31
    }
32
  }
33

8!
34
  getResource(lng, ns, key, options = {}) {
35
    const keySeparator =
36
      options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
37

8✔
38
    const ignoreJSONStructure =
8✔
39
      options.ignoreJSONStructure !== undefined
8!
40
        ? options.ignoreJSONStructure
×
41
        : this.options.ignoreJSONStructure;
42

43
    let path = [lng, ns];
8!
44
    if (key && typeof key !== 'string') path = path.concat(key);
8✔
45
    if (key && typeof key === 'string')
8!
46
      path = path.concat(keySeparator ? key.split(keySeparator) : key);
8✔
47

48
    if (lng.indexOf('.') > -1) {
8!
49
      path = lng.split('.');
8✔
50
    }
51

8✔
52
    const result = utils.getPath(this.data, path);
53
    if (result || !ignoreJSONStructure || typeof key !== 'string') return result;
1✔
54

55
    return utils.deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator);
56
  }
×
57

×
58
  addResource(lng, ns, key, value, options = { silent: false }) {
59
    const keySeparator =
60
      options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
61

62
    let path = [lng, ns];
63
    if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
×
64

×
65
    if (lng.indexOf('.') > -1) {
×
66
      path = lng.split('.');
67
      value = ns;
68
      ns = path[1];
69
    }
70

71
    this.addNamespaces(ns);
117!
72

117✔
73
    utils.setPath(this.data, path, value);
117!
74

117✔
75
    if (!options.silent) this.emit('added', lng, ns, key, value);
117!
76
  }
117!
77

117!
78
  addResources(lng, ns, resources, options = { silent: false }) {
×
79
    /* eslint no-restricted-syntax: 0 */
80
    for (const m in resources) {
117✔
81
      if (
117✔
82
        typeof resources[m] === 'string' ||
76✔
83
        Object.prototype.toString.apply(resources[m]) === '[object Array]'
84
      )
85
        this.addResource(lng, ns, m, resources[m], { silent: true });
86
    }
87
    if (!options.silent) this.emit('added', lng, ns, resources);
×
88
  }
89

90
  addResourceBundle(lng, ns, resources, deep, overwrite, options = { silent: false }) {
×
91
    let path = [lng, ns];
×
92
    if (lng.indexOf('.') > -1) {
×
93
      path = lng.split('.');
×
94
      deep = resources;
×
95
      resources = ns;
×
96
      ns = path[1];
×
97
    }
98

×
99
    this.addNamespaces(ns);
×
100

×
101
    let pack = utils.getPath(this.data, path) || {};
102

103
    if (deep) {
104
      utils.deepExtend(pack, resources, overwrite);
105
    } else {
×
106
      pack = { ...pack, ...resources };
107
    }
108

109
    utils.setPath(this.data, path, pack);
×
110

×
111
    if (!options.silent) this.emit('added', lng, ns, resources);
112
  }
113

114
  removeResourceBundle(lng, ns) {
×
115
    if (this.hasResourceBundle(lng, ns)) {
116
      delete this.data[lng][ns];
117
    }
118
    this.removeNamespaces(ns);
119

×
120
    this.emit('removed', lng, ns);
121
  }
122

×
123
  hasResourceBundle(lng, ns) {
×
124
    return this.getResource(lng, ns) !== undefined;
×
125
  }
×
126

×
127
  getResourceBundle(lng, ns) {
×
128
    if (!ns) ns = this.options.defaultNS;
129

×
130
    // COMPATIBILITY: remove extend in v2.1.0
×
131
    if (this.options.compatibilityAPI === 'v1') return { ...{}, ...this.getResource(lng, ns) };
×
132

×
133
    return this.getResource(lng, ns);
134
  }
×
135

136
  getDataByLanguage(lng) {
×
137
    return this.data[lng];
×
138
  }
139

140
  hasLanguageSomeTranslations(lng) {
141
    const data = this.getDataByLanguage(lng);
142
    const n = (data && Object.keys(data)) || [];
×
143
    return !!n.find((v) => data[v] && Object.keys(data[v]).length > 0);
×
144
  }
145

×
146
  toJSON() {
×
147
    return this.data;
148
  }
149
}
150

151
export default ResourceStore;
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc