mirror of
				https://github.com/datahub-project/datahub.git
				synced 2025-10-31 02:37:05 +00:00 
			
		
		
		
	Merge pull request #1213 from theseyi/moar-propagate
throws more errors on failed schema validation
This commit is contained in:
		
						commit
						d5dfb38a84
					
				| @ -99,7 +99,16 @@ const complianceMetadataTaxonomy: Array<IMetadataType> = [ | |||||||
|  * @param {string | Array<string>} expectedType the pattern string to match against |  * @param {string | Array<string>} expectedType the pattern string to match against | ||||||
|  * @returns {boolean} |  * @returns {boolean} | ||||||
|  */ |  */ | ||||||
| const valueEquiv = (value: any, expectedType: string | Array<string>): boolean => expectedType.includes(typeOf(value)); | const isValueEquiv = (value: any, expectedType: string | Array<string>): true => { | ||||||
|  |   const valueType = typeOf(value); | ||||||
|  |   const isValueOfExpectedType = expectedType.includes(valueType); | ||||||
|  | 
 | ||||||
|  |   if (!isValueOfExpectedType) { | ||||||
|  |     throw new Error(`Expected ${value} to be of type(s) ${expectedType}, got ${valueType}`); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return isValueOfExpectedType; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Extracts the type key and the pattern string from the string mapping into a tuple pair |  * Extracts the type key and the pattern string from the string mapping into a tuple pair | ||||||
| @ -119,27 +128,35 @@ const typePatternMap = (metadataType: IMetadataType): [string, string | Array<st | |||||||
| const keyValueHasMatch = (object: IObject<any>) => (metadataType: IMetadataType): boolean => { | const keyValueHasMatch = (object: IObject<any>) => (metadataType: IMetadataType): boolean => { | ||||||
|   const [name, type] = typePatternMap(metadataType); |   const [name, type] = typePatternMap(metadataType); | ||||||
|   const value = object[name]; |   const value = object[name]; | ||||||
|   const rootValueEquiv = object.hasOwnProperty(name) && valueEquiv(value, type); |   const isRootValueEquiv = object.hasOwnProperty(name) && isValueEquiv(value, type); | ||||||
|   const innerType = metadataType['@props']; |   const innerType = metadataType['@props']; | ||||||
| 
 | 
 | ||||||
|  |   if (!isRootValueEquiv) { | ||||||
|  |     throw new Error(`Expected "${name}" to be a key on object`); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (type.includes('object') && isObject(value)) { |   if (type.includes('object') && isObject(value)) { | ||||||
|     // recurse on object properties
 |     // recurse on object properties
 | ||||||
|     return rootValueEquiv && keysEquiv(value, innerType!); |     return isRootValueEquiv && keysEquiv(value, innerType!); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (type.includes('array') && Array.isArray(value)) { |   if (type.includes('array') && Array.isArray(value)) { | ||||||
|     const { length } = value; |     const { length } = value; | ||||||
| 
 | 
 | ||||||
|  |     if (!length) { | ||||||
|  |       throw new Error(`Expected array for ${name} to not be empty`); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return ( |     return ( | ||||||
|       // recursively reduce on array elements
 |       // recursively reduce on array elements
 | ||||||
|       // ensure the array contains at least on element
 |       // ensure the array contains at least on element
 | ||||||
|       rootValueEquiv && |       isRootValueEquiv && | ||||||
|       length > 0 && |       length > 0 && | ||||||
|       arrayReduce((isEquiv: boolean, value: any) => isEquiv && keysEquiv(value, innerType!), rootValueEquiv)(value) |       arrayReduce((isEquiv: boolean, value: any) => isEquiv && keysEquiv(value, innerType!), isRootValueEquiv)(value) | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return rootValueEquiv; |   return isRootValueEquiv; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -149,7 +166,7 @@ const keyValueHasMatch = (object: IObject<any>) => (metadataType: IMetadataType) | |||||||
|  * @return {boolean} |  * @return {boolean} | ||||||
|  * @throws {Error} if object keys do not match type @names |  * @throws {Error} if object keys do not match type @names | ||||||
|  */ |  */ | ||||||
| const keysMatchNames = (object: IObject<any>, typeMaps: Array<IMetadataType>): boolean => { | const keysMatchNames = (object: IObject<any>, typeMaps: Array<IMetadataType>): true => { | ||||||
|   const objectKeys = Object.keys(object).sort(); |   const objectKeys = Object.keys(object).sort(); | ||||||
|   const typeKeys = arrayMap((typeMap: IMetadataType) => typeMap['@name'])(typeMaps).sort(); |   const typeKeys = arrayMap((typeMap: IMetadataType) => typeMap['@name'])(typeMaps).sort(); | ||||||
|   const objectKeysSerialized = objectKeys.toString(); |   const objectKeysSerialized = objectKeys.toString(); | ||||||
| @ -157,7 +174,12 @@ const keysMatchNames = (object: IObject<any>, typeMaps: Array<IMetadataType>): b | |||||||
|   const match = objectKeysSerialized === typeKeysSerialized; |   const match = objectKeysSerialized === typeKeysSerialized; | ||||||
| 
 | 
 | ||||||
|   if (!match) { |   if (!match) { | ||||||
|     throw new Error(`Extra attributes found: ${difference(objectKeys, typeKeys).join(', ')}`); |     throw new Error( | ||||||
|  |       `Expected attributes ${typeKeys.join(', ')} on object. Found additional  attributes ${difference( | ||||||
|  |         objectKeys, | ||||||
|  |         typeKeys | ||||||
|  |       ).join(', ')}` | ||||||
|  |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return match; |   return match; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Seyi Adebajo
						Seyi Adebajo