import { Observable , of } from 'rxjs' ; import { map , takeWhile } from 'rxjs/operators' ; import { deepCopy } from '@delon/util' ; import { SFSchemaDefinition , SFUISchema , SFUISchemaItem , SFSchema , SFSchemaEnum , SFUISchemaItemRun } from '@delon/form' ; export const FORMATMAPS = { 'date-time' : { widget : 'date' , showTime : true , format : 'YYYY-MM-DDTHH:mm:ssZ' } , date : { widget : 'date' , format : 'YYYY-MM-DD' } , 'full-date' : { widget : 'date' , format : 'YYYY-MM-DD' } , time : { widget : 'time' } , 'full-time' : { widget : 'time' } , week : { widget : 'date' , mode : 'week' , format : 'YYYY-WW' } , month : { widget : 'date' , mode : 'month' , format : 'YYYY-MM' } , uri : { widget : 'upload' } , email : { widget : 'autocomplete' , type : 'email' } , '' : { widget : 'string' } , } ; export function isBlank ( o ) { return o == null ; } export function di ( ... args ) { console . warn ( ... args ) ; } /** 根据 `$ref` 查找 `definitions` */ function findSchemaDefinition ( $ref , definitions = { } ) { const match = /^#\/definitions\/(.*)$/ . exec ( $ref ) ; if ( match && match [ 1 ] ) { const parts = match [ 1 ] . split ( '/' ) ; let current = definitions ; for ( let part of parts ) { part = part . replace ( /~1/g , '/' ) . replace ( /~0/g , '~' ) ; if ( current . hasOwnProperty ( part ) ) { current = current [ part ] ; } else { throw new Error ( `Could not find a definition for ${ $ref }.` ) ; } } return current ; } throw new Error ( `Could not find a definition for ${ $ref }.` ) ; } /**
 * 取回Schema，并处理 `$ref` 的关系
 */ export function retrieveSchema ( schema , definitions = { } ) { if ( schema . hasOwnProperty ( '$ref' ) ) { const $refSchema = findSchemaDefinition ( schema . $ref , definitions ) ; const { $ref , ... localSchema } = schema ; return retrieveSchema ( { ... $refSchema , ... localSchema } , definitions ) ; } return schema ; } export function resolveIf ( schema , ui ) { if ( ! ( schema . hasOwnProperty ( 'if' ) && schema . hasOwnProperty ( 'then' ) ) ) return ; if ( ! schema . if . properties ) throw new Error ( `if: does not contain 'properties'` ) ; const allKeys = Object . keys ( schema . properties ) , ifKeys = Object . keys ( schema . if . properties ) ; detectKey ( allKeys , ifKeys ) ; detectKey ( allKeys , schema . then . required ) ; schema . required = schema . required . concat ( schema . then . required ) ; const hasElse = schema . hasOwnProperty ( 'else' ) ; if ( hasElse ) { detectKey ( allKeys , schema . else . required ) ; schema . required = schema . required . concat ( schema . else . required ) ; } const visibleIf = { } ; const visibleElse = { } ; ifKeys . forEach ( key => { const cond = schema . if . properties [ key ] . enum ; visibleIf [ key ] = cond ; if ( hasElse ) visibleElse [ key ] = ( value ) => ! cond . includes ( value ) ; } ) ; schema . then . required . forEach ( key => ( ui [ `$${ key }` ] . visibleIf = visibleIf ) ) ; if ( hasElse ) schema . else . required . forEach ( key => ( ui [ `$${ key }` ] . visibleIf = visibleElse ) ) ; return schema ; } function detectKey ( keys , detectKeys ) { detectKeys . forEach ( key => { if ( ! keys . includes ( key ) ) { throw new Error ( `if: properties does not contain '${ key }'` ) ; } } ) ; } export function orderProperties ( properties , order ) { if ( ! Array . isArray ( order ) ) return properties ; const arrayToHash = arr => arr . reduce ( ( prev , curr ) => { prev [ curr ] = true ; return prev ; } , { } ) ; const errorPropList = arr => arr . length > 1 ? `properties '${ arr . join ( `', '` ) }'` : `property '${ arr [ 0 ] }'` ; const propertyHash = arrayToHash ( properties ) ; const orderHash = arrayToHash ( order ) ; const extraneous = order . filter ( prop => prop !== '*' && ! propertyHash [ prop ] ) ; if ( extraneous . length ) { throw new Error ( `ui schema order list contains extraneous ${ errorPropList ( extraneous ) }` ) ; } const rest = properties . filter ( prop => ! orderHash [ prop ] ) ; const restIndex = order . indexOf ( '*' ) ; if ( restIndex === - 1 ) { if ( rest . length ) { throw new Error ( `ui schema order list does not contain ${ errorPropList ( rest ) }` ) ; } return order ; } if ( restIndex !== order . lastIndexOf ( '*' ) ) { throw new Error ( 'ui schema order list contains more than one wildcard item' ) ; } const complete = [ ... order ] ; complete . splice ( restIndex , 1 , ... rest ) ; return complete ; } export function getUiOptions ( uiSchema ) { if ( ! uiSchema ) return { } ; return Object . keys ( uiSchema ) . filter ( key => ! key . startsWith ( '$' ) ) . reduce ( ( options , key ) => { return { ... options , [ key ] : uiSchema [ key ] } ; } , < SFUISchemaItem > { } ) ; } export function getEnum ( list , formData ) { if ( isBlank ( list ) || ! Array . isArray ( list ) || list . length === 0 ) return [ ] ; if ( typeof list [ 0 ] !== 'object' ) { list = list . map ( ( item ) => { return < SFSchemaEnum > { label : item , value : item } ; } ) ; } if ( formData ) { if ( ! Array . isArray ( formData ) ) formData = [ formData ] ; list . forEach ( ( item ) => { if ( ~ formData . indexOf ( item . value ) ) item . checked = true ; } ) ; } return list ; } export function getCopyEnum ( list , formData ) { return getEnum ( deepCopy ( list || [ ] ) , formData ) ; } export function getData ( schema , ui , formData , asyncArgs ? ) { if ( typeof ui . asyncData === 'function' ) { return ui . asyncData ( asyncArgs ) . pipe ( takeWhile ( ( ) => ui . __destroy !== true ) , map ( list => getEnum ( list , formData ) ) ) ; } return of ( getCopyEnum ( schema . enum , formData ) ) ; }