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

i18next / i18next / #34050

02 Jan 2024 10:08AM UTC coverage: 92.045% (+1.3%) from 90.766%
#34050

push

adrai
try to fix circleci

1558 of 2443 branches covered (63.77%)

1481 of 1609 relevant lines covered (92.04%)

1239.15 hits per line

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

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

40,412!
4
class ResourceStore extends EventEmitter {
1✔
5
  constructor(data, options = { ns: ['translation'], defaultNS: 'translation' }) {
6
    super();
7

1✔
8
    this.data = data || {};
1✔
9
    this.options = options;
1✔
10
    if (this.options.keySeparator === undefined) {
×
11
      this.options.keySeparator = '.';
1!
12
    }
1!
13
    if (this.options.ignoreJSONStructure === undefined) {
20,266!
14
      this.options.ignoreJSONStructure = true;
20,266!
15
    }
20,148!
16
  }
92!
17

12!
18
  addNamespaces(ns) {
1!
19
    if (this.options.ns.indexOf(ns) < 0) {
20,160!
20
      this.options.ns.push(ns);
20,160!
21
    }
1!
22
  }
1!
23

92!
24
  removeNamespaces(ns) {
92!
25
    const index = this.options.ns.indexOf(ns);
×
26
    if (index > -1) {
1!
27
      this.options.ns.splice(index, 1);
1!
28
    }
1✔
29
  }
1✔
30

1✔
31
  getResource(lng, ns, key, options = {}) {
32
    const keySeparator =
33
      options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
92✔
34

35
    const ignoreJSONStructure =
36
      options.ignoreJSONStructure !== undefined
37
        ? options.ignoreJSONStructure
92✔
38
        : this.options.ignoreJSONStructure;
92✔
39

92✔
40
    let path = [lng, ns];
92✔
41
    if (key && typeof key !== 'string') path = path.concat(key);
92✔
42
    if (key && typeof key === 'string')
59✔
43
      path = path.concat(keySeparator ? key.split(keySeparator) : key);
44

92✔
45
    if (lng.indexOf('.') > -1) {
82✔
46
      path = lng.split('.');
47
    }
92✔
48

49
    const result = utils.getPath(this.data, path);
1✔
50
    if (result || !ignoreJSONStructure || typeof key !== 'string') return result;
51

52
    return utils.deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator);
10,160✔
53
  }
10,126✔
54

55
  addResource(lng, ns, key, value, options = { silent: false }) {
56
    const keySeparator =
57
      options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
58

59
    let path = [lng, ns];
2✔
60
    if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
2!
61

2✔
62
    if (lng.indexOf('.') > -1) {
63
      path = lng.split('.');
64
      value = ns;
65
      ns = path[1];
66
    }
67

11,001✔
68
    this.addNamespaces(ns);
11,001✔
69

11,001!
70
    utils.setPath(this.data, path, value);
11,001✔
71

11,001!
72
    if (!options.silent) this.emit('added', lng, ns, key, value);
11,001✔
73
  }
11,001✔
74

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

23!
87
  addResourceBundle(lng, ns, resources, deep, overwrite, options = { silent: false }) {
23✔
88
    let path = [lng, ns];
23!
89
    if (lng.indexOf('.') > -1) {
23✔
90
      path = lng.split('.');
2✔
91
      deep = resources;
2✔
92
      resources = ns;
2✔
93
      ns = path[1];
94
    }
23✔
95

23✔
96
    this.addNamespaces(ns);
23✔
97

98
    let pack = utils.getPath(this.data, path) || {};
99

100
    if (deep) {
101
      utils.deepExtend(pack, resources, overwrite);
4✔
102
    } else {
103
      pack = { ...pack, ...resources };
104
    }
105

4✔
106
    utils.setPath(this.data, path, pack);
7!
107

108
    if (!options.silent) this.emit('added', lng, ns, resources);
109
  }
110

4✔
111
  removeResourceBundle(lng, ns) {
112
    if (this.hasResourceBundle(lng, ns)) {
113
      delete this.data[lng][ns];
114
    }
115
    this.removeNamespaces(ns);
10,137✔
116

117
    this.emit('removed', lng, ns);
118
  }
10,137✔
119

10,137✔
120
  hasResourceBundle(lng, ns) {
3✔
121
    return this.getResource(lng, ns) !== undefined;
3✔
122
  }
3✔
123

3✔
124
  getResourceBundle(lng, ns) {
125
    if (!ns) ns = this.options.defaultNS;
10,137✔
126

10,137✔
127
    // COMPATIBILITY: remove extend in v2.1.0
10,137✔
128
    if (this.options.compatibilityAPI === 'v1') return { ...{}, ...this.getResource(lng, ns) };
4✔
129

130
    return this.getResource(lng, ns);
10,133✔
131
  }
132

10,137✔
133
  getDataByLanguage(lng) {
10,137✔
134
    return this.data[lng];
135
  }
136

137
  hasLanguageSomeTranslations(lng) {
138
    const data = this.getDataByLanguage(lng);
2!
139
    const n = (data && Object.keys(data)) || [];
2✔
140
    return !!n.find((v) => data[v] && Object.keys(data[v]).length > 0);
141
  }
2✔
142

2✔
143
  toJSON() {
144
    return this.data;
145
  }
146
}
147

10,360✔
148
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