diff --git a/.changeset/cuddly-timers-sin.md b/.changeset/cuddly-timers-sin.md new file mode 100644 index 000000000..1cb781b8d --- /dev/null +++ b/.changeset/cuddly-timers-sin.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': patch +--- + +LocalizeManager: added `allowOverridesForExistingNamespaces` option to `constructor` argument to allow for changing data in a namespace for a given locale diff --git a/packages/ui/components/localize/src/LocalizeManager.js b/packages/ui/components/localize/src/LocalizeManager.js index 959ffdb43..43dd39814 100644 --- a/packages/ui/components/localize/src/LocalizeManager.js +++ b/packages/ui/components/localize/src/LocalizeManager.js @@ -18,6 +18,7 @@ export class LocalizeManager { autoLoadOnLocaleChange = false, fallbackLocale = '', showKeyAsFallback = false, + allowOverridesForExistingNamespaces = false, } = {}) { /** @private */ this.__delegationTarget = document.createDocumentFragment(); @@ -28,6 +29,9 @@ export class LocalizeManager { /** @protected */ this._showKeyAsFallback = showKeyAsFallback; + /** @private */ + this.__allowOverridesForExistingNamespaces = allowOverridesForExistingNamespaces; + /** * @type {Object.>} * @private @@ -199,17 +203,29 @@ export class LocalizeManager { * @param {string} locale * @param {string} namespace * @param {object} data - * @throws {Error} Namespace can be added only once, for a given locale + * @throws {Error} Namespace can be added only once, for a given locale unless allowOverridesForExistingNamespaces + * is set to `true` */ addData(locale, namespace, data) { - if (this._isNamespaceInCache(locale, namespace)) { + if ( + !this.__allowOverridesForExistingNamespaces && + this._isNamespaceInCache(locale, namespace) + ) { throw new Error( `Namespace "${namespace}" has been already added for the locale "${locale}".`, ); } this.__storage[locale] = this.__storage[locale] || {}; - this.__storage[locale][namespace] = data; + + if (this.__allowOverridesForExistingNamespaces) { + this.__storage[locale][namespace] = { + ...this.__storage[locale][namespace], + ...data, + }; + } else { + this.__storage[locale][namespace] = data; + } } /** diff --git a/packages/ui/components/localize/test/LocalizeManager.test.js b/packages/ui/components/localize/test/LocalizeManager.test.js index 00b0b0cae..5b750641d 100644 --- a/packages/ui/components/localize/test/LocalizeManager.test.js +++ b/packages/ui/components/localize/test/LocalizeManager.test.js @@ -155,7 +155,7 @@ describe('LocalizeManager', () => { }); }); - it('prevents mutating existing data for the same locale & namespace', () => { + it('prevents mutating existing data for the same locale & namespace when "allowOverridesForExistingNamespaces" option is not given in constructor', () => { manager = new LocalizeManager(); const { storage } = getProtectedMembers(manager); @@ -169,6 +169,23 @@ describe('LocalizeManager', () => { 'en-GB': { 'lion-hello': { greeting: 'Hi!' } }, }); }); + + it('allows mutating existing data for the same locale & namespace when "allowOverridesForExistingNamespaces" option is set to "true" in constructor', () => { + manager = new LocalizeManager({ allowOverridesForExistingNamespaces: true }); + const { storage } = getProtectedMembers(manager); + + manager.addData('en-GB', 'lion-hello', { greeting: 'Hi!' }); + + expect(storage).to.deep.equal({ + 'en-GB': { 'lion-hello': { greeting: 'Hi!' } }, + }); + + manager.addData('en-GB', 'lion-hello', { greeting: 'Hi!', alternative: 'Hello!' }); + + expect(storage).to.deep.equal({ + 'en-GB': { 'lion-hello': { greeting: 'Hi!', alternative: 'Hello!' } }, + }); + }); }); describe('loading via dynamic imports', () => {