import isEmpty from 'lodash/isEmpty' ; import startCase from 'lodash/startCase' ; import keys from 'lodash/keys' ; import { ControlElement , isGroup , isLayout , JsonSchema , LabelElement , Layout , UISchemaElement } from '../models' ; import { deriveTypes , resolveSchema } from '../util' ; param layoutType returns const createLayout = ( layoutType ) : Layout => ( { type : layoutType , elements : [ ] } ) ; /**
 * Creates a IControlObject with the given label referencing the given ref
 */ export const createControlElement = ( ref ) : ControlElement => ( { type : 'Control' , scope : ref } ) ; param uischema param layoutType returns const wrapInLayoutIfNecessary = ( uischema , layoutType ) : Layout => { if ( ! isEmpty ( uischema ) && ! isLayout ( uischema ) ) { const verticalLayout = createLayout ( layoutType ) ; verticalLayout . elements . push ( uischema ) ; return verticalLayout ; } return uischema as Layout ; } ; param layout param labelName const addLabel = ( layout , labelName ) => { if ( ! isEmpty ( labelName ) ) { const fixedLabel = startCase ( labelName ) ; if ( isGroup ( layout ) ) { layout . label = fixedLabel ; } else { const label = { type : 'Label' , text : fixedLabel } ; layout . elements . push ( label ) ; } } } ; param jsonSchema const isCombinator = ( jsonSchema ) : boolean => { return ( ! isEmpty ( jsonSchema ) && ( ! isEmpty ( jsonSchema . oneOf ) || ! isEmpty ( jsonSchema . anyOf ) || ! isEmpty ( jsonSchema . allOf ) ) ) ; } ; const generateUISchema = ( jsonSchema , schemaElements , currentRef , schemaName , layoutType , rootSchema ? ) : UISchemaElement => { if ( ! isEmpty ( jsonSchema ) && jsonSchema . $ref !== undefined ) { return generateUISchema ( resolveSchema ( rootSchema , jsonSchema . $ref ) , schemaElements , currentRef , schemaName , layoutType , rootSchema ) ; } if ( isCombinator ( jsonSchema ) ) { const controlObject = createControlElement ( currentRef ) ; schemaElements . push ( controlObject ) ; return controlObject ; } const types = deriveTypes ( jsonSchema ) ; if ( types . length === 0 ) { return null ; } if ( types . length > 1 ) { const controlObject = createControlElement ( currentRef ) ; schemaElements . push ( controlObject ) ; return controlObject ; } if ( currentRef === '#' && types [ 0 ] === 'object' ) { const layout = createLayout ( layoutType ) ; schemaElements . push ( layout ) ; if ( jsonSchema . properties && keys ( jsonSchema . properties ) . length > 1 ) { addLabel ( layout , schemaName ) ; } if ( ! isEmpty ( jsonSchema . properties ) ) { const nextRef = currentRef + '/properties' ; Object . keys ( jsonSchema . properties ) . map ( propName => { let value = jsonSchema . properties [ propName ] ; const ref = `${ nextRef }/${ propName }` ; if ( value . $ref !== undefined ) { value = resolveSchema ( rootSchema , value . $ref ) ; } generateUISchema ( value , layout . elements , ref , propName , layoutType , rootSchema ) ; } ) ; } return layout ; } switch ( types [ 0 ] ) { case 'object' : case 'array' : case 'string' : case 'number' : case 'integer' : case 'boolean' : const controlObject = createControlElement ( currentRef ) ; schemaElements . push ( controlObject ) ; return controlObject ; default : throw new Error ( 'Unknown type: ' + JSON . stringify ( jsonSchema ) ) ; } } ; param { JsonSchema } jsonSchema param { string } layoutType export const generateDefaultUISchema = ( jsonSchema , layoutType = 'VerticalLayout' , prefix = '#' , rootSchema = jsonSchema ) : UISchemaElement => wrapInLayoutIfNecessary ( generateUISchema ( jsonSchema , [ ] , prefix , '' , layoutType , rootSchema ) , layoutType ) ;