import isEmpty from 'lodash/isEmpty' ; import get from 'lodash/get' ; import { JsonSchema } from '../models' ; /**
 * Map for storing refs and the respective schemas they are pointing to.
 */ export interface ReferenceSchemaMap { [ ref ] : JsonSchema ; } const isObjectSchema = ( schema ) : boolean => { return schema . properties !== undefined ; } ; const isArraySchema = ( schema ) : boolean => { return schema . type === 'array' && schema . items !== undefined ; } ; export const resolveData = ( instance , dataPath ) : any => { if ( isEmpty ( dataPath ) ) { return instance ; } const dataPathSegments = dataPath . split ( '.' ) ; return dataPathSegments . map ( segment => decodeURIComponent ( segment ) ) . reduce ( ( curInstance , decodedSegment ) => { if ( ! curInstance || ! curInstance . hasOwnProperty ( decodedSegment ) ) { return undefined ; } return curInstance [ decodedSegment ] ; } , instance ) ; } ; param schema The  JsonSchema to find the references in
 *  param result param resolveTuples export const findAllRefs = ( schema , result = { } , resolveTuples = false ) : ReferenceSchemaMap => { if ( isObjectSchema ( schema ) ) { Object . keys ( schema . properties ) . forEach ( key => findAllRefs ( schema . properties [ key ] , result ) ) ; } if ( isArraySchema ( schema ) ) { if ( Array . isArray ( schema . items ) ) { if ( resolveTuples ) { const items = schema . items ; items . forEach ( child => findAllRefs ( child , result ) ) ; } } else { findAllRefs ( schema . items , result ) ; } } if ( Array . isArray ( schema . anyOf ) ) { const anyOf = schema . anyOf ; anyOf . forEach ( child => findAllRefs ( child , result ) ) ; } if ( schema . $ref !== undefined ) { result [ schema . $ref ] = schema ; } return result ; } ; const invalidSegment = ( pathSegment ) => pathSegment === '#' || pathSegment === undefined || pathSegment === '' ; param { JsonSchema } schema param { string } schemaPath param { JsonSchema } rootSchema returns { JsonSchema } export const resolveSchema = ( schema , schemaPath , rootSchema ? ) : JsonSchema => { if ( isEmpty ( schema ) ) { return undefined ; } const validPathSegments = schemaPath . split ( '/' ) ; let resultSchema = schema ; for ( let i = 0 ; i < validPathSegments . length ; i ++ ) { let pathSegment = validPathSegments [ i ] ; resultSchema = resultSchema === undefined || resultSchema . $ref === undefined ? resultSchema : resolveSchema ( schema , resultSchema . $ref ) ; if ( invalidSegment ( pathSegment ) ) { continue ; } let curSchema = get ( resultSchema , pathSegment ) ; if ( ! curSchema ) { const schemas = [ ] . concat ( resultSchema ?. oneOf ?? [ ] , resultSchema ?. allOf ?? [ ] , resultSchema ?. anyOf ?? [ ] ) ; for ( let item of schemas ) { curSchema = resolveSchema ( item , validPathSegments . slice ( i ) . join ( '/' ) ) ; if ( curSchema ) { break ; } } if ( curSchema ) { resultSchema = curSchema ; break ; } } resultSchema = curSchema ; } if ( resultSchema !== undefined && resultSchema . $ref !== undefined ) { try { return retrieveResolvableSchema ( schema , resultSchema . $ref ) ; } catch ( e ) { return retrieveResolvableSchema ( rootSchema , resultSchema . $ref ) ; } } return resultSchema ; } ; param { JsonSchema } full param { string } reference returns { JsonSchema } function retrieveResolvableSchema ( full , reference ) { const child = resolveSchema ( full , reference ) ; const allRefs = findAllRefs ( child ) ; const innerSelfReference = allRefs [ reference ] ; if ( innerSelfReference !== undefined ) { innerSelfReference . $ref = '#' ; } return child ; }