From ff8e40d4254caf5c1370e12a189df4bc572416e0 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 30 Mar 2021 10:15:32 +0100 Subject: [PATCH] support replacing values on merge (#6875) --- .../src/lib/config/extension-utils.spec.ts | 109 ++++++++++++++++++ .../src/lib/config/extension-utils.ts | 12 +- 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 lib/extensions/src/lib/config/extension-utils.spec.ts diff --git a/lib/extensions/src/lib/config/extension-utils.spec.ts b/lib/extensions/src/lib/config/extension-utils.spec.ts new file mode 100644 index 00000000000..feee173bc46 --- /dev/null +++ b/lib/extensions/src/lib/config/extension-utils.spec.ts @@ -0,0 +1,109 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mergeObjects } from './extension-utils'; + +// tslint:disable-next-line:ban +fdescribe('Extension Utils', () => { + describe('mergeObjects', () => { + it('should merge two objects', () => { + const obj1 = { aHello: 1 }; + const obj2 = { bWorld: 2 }; + + const result = mergeObjects(obj1, obj2); + + expect(result).toEqual({ + aHello: 1, + bWorld: 2 + }); + }); + + it('should merge three objects', () => { + const obj1 = { aHello: 1 }; + const obj2 = { bWorld: 2 }; + const obj3 = { aHello: 3 }; + + const result = mergeObjects(obj1, obj2, obj3); + + expect(result).toEqual({ + aHello: 3, + bWorld: 2 + }); + }); + + it('should not process special properties starting with $', () => { + const obj1 = { '$id': 'uid', aHello: 1 }; + const obj2 = { '$schema': 'schema-id', bWorld: 2 }; + + const result = mergeObjects(obj1, obj2); + + expect(result).toEqual({ + aHello: 1, + bWorld: 2 + }); + }); + + it('should merge arrays', () => { + const obj1 = { values: ['one', 'two'] }; + const obj2 = { values: ['three', 'four'] }; + + const result = mergeObjects(obj1, obj2); + + expect(result).toEqual({ + values: ['one', 'two', 'three', 'four'] + }); + }); + + it('should replace array', () => { + const obj1 = { values: ['one', 'two'] }; + const obj2 = { 'values.$replace': ['three', 'four'] }; + + const result = mergeObjects(obj1, obj2); + + expect(result).toEqual({ + values: ['three', 'four'] + }); + }); + + it('should replace objects', () => { + const obj1 = { values: { tag: 'test' } }; + const obj2 = { 'values.$replace': { hello: 'world' } }; + + const result = mergeObjects(obj1, obj2); + + expect(result).toEqual({ + values: { hello: 'world' } + }); + }); + + it('should replace nested objects', () => { + const obj1 = { level1: { level2: { name: 'level2' } } }; + const obj2 = { level1: { 'level2.$replace': { name: 'modified', tag: 'node' } } }; + + const result = mergeObjects(obj1, obj2); + + expect(result).toEqual({ + level1: { + level2: { + name: 'modified', + tag: 'node' + } + } + }); + }); + }); +}); diff --git a/lib/extensions/src/lib/config/extension-utils.ts b/lib/extensions/src/lib/config/extension-utils.ts index a8a120418ea..78ea128c460 100644 --- a/lib/extensions/src/lib/config/extension-utils.ts +++ b/lib/extensions/src/lib/config/extension-utils.ts @@ -107,9 +107,17 @@ export function mergeObjects(...objects: object[]): any { objects.forEach((source) => { Object.keys(source).forEach((prop) => { + let replace = false; + + if (prop.endsWith('.$replace')) { + replace = true; + prop = prop.replace('.$replace', ''); + } + if (!prop.startsWith('$')) { - if (prop in result && Array.isArray(result[prop])) { - // result[prop] = result[prop].concat(source[prop]); + if (replace) { + result[prop] = source[`${prop}.$replace`]; + } else if (prop in result && Array.isArray(result[prop])) { result[prop] = mergeArrays(result[prop], source[prop]); } else if (prop in result && typeof result[prop] === 'object') { result[prop] = mergeObjects(result[prop], source[prop]);