mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 10:33:44 +03:00
Merge theme deeply
This commit is contained in:
parent
0bd8c66090
commit
ed13bb0528
|
@ -1,5 +1,5 @@
|
|||
import { ThemeInterface } from '../theme';
|
||||
import { isNumeric } from '../utils/helpers';
|
||||
import { isNumeric, mergeObjects } from '../utils/helpers';
|
||||
import defaultTheme from '../theme';
|
||||
|
||||
export interface RedocRawOptions {
|
||||
|
@ -33,7 +33,7 @@ export class RedocNormalizedOptions {
|
|||
untrustedSpec: boolean;
|
||||
|
||||
constructor(raw: RedocRawOptions) {
|
||||
this.theme = { ...(raw.theme || {}), ...defaultTheme }; // todo: merge deep
|
||||
this.theme = mergeObjects({} as any, raw.theme || {}, defaultTheme);
|
||||
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
|
||||
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
||||
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { mapWithLast, appendToMdHeading } from '../helpers';
|
||||
import { mapWithLast, appendToMdHeading, mergeObjects } from '../helpers';
|
||||
|
||||
describe('Utils', () => {
|
||||
describe('helpers', () => {
|
||||
|
@ -38,5 +38,24 @@ describe('Utils', () => {
|
|||
const val = appendToMdHeading('', 'Authentication', '<test>');
|
||||
expect(val).toEqual('# Authentication\n\n<test>');
|
||||
});
|
||||
|
||||
describe('mergeObjects', () => {
|
||||
test('should merge Objects and all nested Ones', () => {
|
||||
const obj1 = { a: { a1: 'A1' }, c: 'C', d: {} };
|
||||
const obj2 = { a: { a2: 'A2' }, b: { b1: 'B1' }, d: null };
|
||||
const obj3 = { a: { a1: 'A1', a2: 'A2' }, b: { b1: 'B1' }, c: 'C', d: null };
|
||||
expect(mergeObjects({}, obj1, obj2)).toEqual(obj3);
|
||||
});
|
||||
test('should behave like Object.assign on the top level', () => {
|
||||
const obj1 = { a: { a1: 'A1' }, c: 'C' };
|
||||
const obj2 = { a: undefined, b: { b1: 'B1' } };
|
||||
expect(mergeObjects({}, obj1, obj2)).toEqual(Object.assign({}, obj1, obj2));
|
||||
});
|
||||
test('should not merge array values, just override', () => {
|
||||
const obj1 = { a: ['A', 'B'] };
|
||||
const obj2 = { a: ['C'], b: ['D'] };
|
||||
expect(mergeObjects({}, obj1, obj2)).toEqual({ a: ['C'], b: ['D'] });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,3 +80,37 @@ export function appendToMdHeading(md: string, heading: string, content: string)
|
|||
return `${md}${br}# ${heading}\n\n${content}`;
|
||||
}
|
||||
}
|
||||
|
||||
// credits https://stackoverflow.com/a/46973278/1749888
|
||||
export const mergeObjects = <T extends object = object>(target: T, ...sources: T[]): T => {
|
||||
if (!sources.length) {
|
||||
return target;
|
||||
}
|
||||
const source = sources.shift();
|
||||
if (source === undefined) {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (isMergebleObject(target) && isMergebleObject(source)) {
|
||||
Object.keys(source).forEach(function(key: string) {
|
||||
if (isMergebleObject(source[key])) {
|
||||
if (!target[key]) {
|
||||
target[key] = {};
|
||||
}
|
||||
mergeObjects(target[key], source[key]);
|
||||
} else {
|
||||
target[key] = source[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mergeObjects(target, ...sources);
|
||||
};
|
||||
|
||||
const isObject = (item: any): boolean => {
|
||||
return item !== null && typeof item === 'object';
|
||||
};
|
||||
|
||||
const isMergebleObject = (item): boolean => {
|
||||
return isObject(item) && !Array.isArray(item);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user