[ACA-1597] allow extensions overwrite existing settings (#523)

* merge objects within the arrays

* metadata properties

* code cleanup
This commit is contained in:
Denys Vuika
2018-07-20 14:46:43 +01:00
committed by GitHub
parent 8c9ffc1160
commit 3ab9cee163
7 changed files with 136 additions and 38 deletions

View File

@@ -74,8 +74,8 @@ export class ExtensionService implements RuleContext {
this.loadConfig(this.configPath, 0).then(result => {
let config = result.config;
if (config.references && config.references.length > 0) {
const plugins = config.references.map(
if (config.$references && config.$references.length > 0) {
const plugins = config.$references.map(
(name, idx) => this.loadConfig(`${this.pluginsPath}/${name}`, idx)
);
@@ -86,7 +86,7 @@ export class ExtensionService implements RuleContext {
.map(entry => entry.config);
if (configs.length > 0) {
config = this.mergeConfigs(config, ...configs);
config = this.mergeObjects(config, ...configs);
}
this.setup(config);
@@ -411,23 +411,50 @@ export class ExtensionService implements RuleContext {
return false;
}
// todo: requires overwrite support for array entries
// todo: overwrite only particular areas, don't touch version or other top-level props
protected mergeConfigs(...objects): any {
mergeObjects(...objects): any {
const result = {};
objects.forEach(source => {
Object.keys(source).forEach(prop => {
if (prop in result && Array.isArray(result[prop])) {
result[prop] = result[prop].concat(source[prop]);
} else if (prop in result && typeof result[prop] === 'object') {
result[prop] = this.mergeConfigs(result[prop], source[prop]);
} else {
result[prop] = source[prop];
if (!prop.startsWith('$')) {
if (prop in result && Array.isArray(result[prop])) {
// result[prop] = result[prop].concat(source[prop]);
result[prop] = this.mergeArrays(result[prop], source[prop]);
} else if (prop in result && typeof result[prop] === 'object') {
result[prop] = this.mergeObjects(result[prop], source[prop]);
} else {
result[prop] = source[prop];
}
}
});
});
return result;
}
mergeArrays(left: any[], right: any[]): any[] {
const result = [];
const map = {};
(left || []).forEach(entry => {
const element = entry;
if (element && element.hasOwnProperty('id')) {
map[element.id] = element;
} else {
result.push(element);
}
});
(right || []).forEach(entry => {
const element = entry;
if (element && element.hasOwnProperty('id') && map[element.id]) {
const merged = this.mergeObjects(map[element.id], element);
map[element.id] = merged;
} else {
result.push(element);
}
});
return Object.values(map).concat(result);
}
}