mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-31 07:47:29 +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