Skip to content

Commit

Permalink
prevent resource mutation when using addResourceBundle fixes #2081
Browse files Browse the repository at this point in the history
  • Loading branch information
adrai committed Feb 17, 2024
1 parent 4ce76ae commit d2d7608
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 23.8.3

- prevent resource mutation when using `addResourceBundle` [2081](https://github.com/i18next/i18next/issues/2081)

## 23.8.2

- optimize `addResources` to address [2130](https://github.com/i18next/i18next/issues/2130)
Expand Down
8 changes: 6 additions & 2 deletions i18next.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@
}
addResourceBundle(lng, ns, resources, deep, overwrite) {
let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
silent: false
silent: false,
skipCopy: false
};
let path = [lng, ns];
if (lng.indexOf('.') > -1) {
Expand All @@ -414,6 +415,7 @@
}
this.addNamespaces(ns);
let pack = getPath(this.data, path) || {};
if (!options.skipCopy) resources = JSON.parse(JSON.stringify(resources));
if (deep) {
deepExtend(pack, resources, overwrite);
} else {
Expand Down Expand Up @@ -1653,7 +1655,9 @@
const ns = s[1];
if (err) this.emit('failedLoading', lng, ns, err);
if (data) {
this.store.addResourceBundle(lng, ns, data);
this.store.addResourceBundle(lng, ns, data, undefined, undefined, {
skipCopy: true
});
}
this.state[name] = err ? -1 : 2;
const loaded = {};
Expand Down
2 changes: 1 addition & 1 deletion i18next.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/BackendConnector.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Connector extends EventEmitter {
if (err) this.emit('failedLoading', lng, ns, err);

if (data) {
this.store.addResourceBundle(lng, ns, data);
this.store.addResourceBundle(lng, ns, data, undefined, undefined, { skipCopy: true });
}

// set loaded
Expand Down
11 changes: 10 additions & 1 deletion src/ResourceStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,14 @@ class ResourceStore extends EventEmitter {
if (!options.silent) this.emit('added', lng, ns, resources);
}

addResourceBundle(lng, ns, resources, deep, overwrite, options = { silent: false }) {
addResourceBundle(
lng,
ns,
resources,
deep,
overwrite,
options = { silent: false, skipCopy: false },
) {
let path = [lng, ns];
if (lng.indexOf('.') > -1) {
path = lng.split('.');
Expand All @@ -109,6 +116,8 @@ class ResourceStore extends EventEmitter {

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

if (!options.skipCopy) resources = JSON.parse(JSON.stringify(resources)); // make a copy to fix #2081

if (deep) {
utils.deepExtend(pack, resources, overwrite);
} else {
Expand Down
13 changes: 13 additions & 0 deletions test/runtime/i18next.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,19 @@ describe('i18next', () => {
});
});

it('it adds resources by addResourceBundle without mutating the input resources', () => {
const base = { k1: { k2: 'v' } };
i18next.addResourceBundle('en', 'ns1', base);
expect(base.k1.k2).to.eql('v');
i18next.addResourceBundle('en', 'ns1', { k1: { k2: 'v for ns1' } }, true, true);
expect(base.k1.k2).to.eql('v');
i18next.addResourceBundle('en', 'ns2', base);
expect(base.k1.k2).to.eql('v');
i18next.addResourceBundle('en', 'ns2', { k1: { k2: 'v for ns2' } }, true, true);
expect(base.k1.k2).to.eql('v');
expect(i18next.t('ns1:k1.k2')).to.eql('v for ns1');
});

describe('can remove resources bundle', () => {
it('it removes resources by removeResourceBundle', () => {
i18next.removeResourceBundle('en', 'translation');
Expand Down

0 comments on commit d2d7608

Please sign in to comment.