import { APIFactory } from '@statoscope/extensions' ; import { RelationItem } from '@statoscope/types/types' ; import { RuleDescriptor } from '@statoscope/types/types/validation/api' ; import makeIndex , { IndexAPI } from '@statoscope/helpers/dist/indexer' ; import { Format , Item } from './generator' ; export type API = { getItems : ( compilationId : string | null , type ? : RelationItem [ 'type' ] | null , relatedId ? : string | number ) => Item [ ] ; getItemById ( id ) : Item | null ; getRule ( id ) : RuleDescriptor | null ; } ; type CompilationIndexItem = { id : string | null ; relationTypeIndex : IndexAPI < RelationItem [ 'type' ] , TypeIndexItem > ; itemIndex : IndexAPI < Item [ 'id' ] , Item > ; } ; type TypeIndexItem = { type : RelationItem [ 'type' ] ; relationIdIndex : IndexAPI < RelationItem [ 'id' ] , IdIndexItem > ; itemIndex : IndexAPI < Item [ 'id' ] , Item > ; } ; type IdIndexItem = { id : RelationItem [ 'id' ] ; index : IndexAPI < RelationItem [ 'id' ] , Item > ; } ; const makeAPI = ( source ) => { const idIndex = makeIndex ( ( entity ) => entity . id ) ; const compilationIndex = makeIndex ( ( entity ) => entity . id ) ; const ruleIndex = makeIndex ( ( item ) => item . name , source . payload . rules ) ; for ( const compilation of source . payload . compilations ) { let compilationItem = compilationIndex . get ( compilation . id ) ; if ( ! compilationItem ) { compilationItem = { id : compilation . id , relationTypeIndex : makeIndex ( ( entity ) => entity . type ) , itemIndex : makeIndex ( ( entity ) => entity . id ) , } ; compilationIndex . add ( compilationItem ) ; } for ( const item of compilation . items ) { compilationItem . itemIndex . add ( item ) ; idIndex . add ( item ) ; for ( const related of item . related ) { let typeItem = compilationItem . relationTypeIndex . get ( related . type ) ; if ( ! typeItem ) { typeItem = { type : related . type , relationIdIndex : makeIndex ( ( entity ) => entity . id ) , itemIndex : makeIndex ( ( entity ) => entity . id ) , } ; compilationItem . relationTypeIndex . add ( typeItem ) ; } let idItem = typeItem . relationIdIndex . get ( related . id ) ; if ( ! idItem ) { idItem = { id : related . id , index : makeIndex ( ( entity ) => entity . id ) , } ; typeItem . relationIdIndex . add ( idItem ) ; } typeItem . itemIndex . add ( item ) ; idItem . index . add ( item ) ; } } } return { getItems : ( compilationId , type ? , relatedId ? ) : Item [ ] => { if ( relatedId ) { if ( ! type ) { throw new Error ( 'type must be specified' ) ; } return ( compilationIndex . get ( compilationId ) ?. relationTypeIndex . get ( type ) ?. relationIdIndex . get ( relatedId ) ?. index . getAll ( ) ?? [ ] ) ; } if ( type ) { return ( compilationIndex . get ( compilationId ) ?. relationTypeIndex . get ( type ) ?. itemIndex . getAll ( ) ?? [ ] ) ; } return compilationIndex . get ( compilationId ) ?. itemIndex . getAll ( ) ?? [ ] ; } , getRule ( id ) { return ruleIndex . get ( id ) ?. descriptor || null ; } , getItemById ( id ) { return idIndex . get ( id ) ; } , } ; } ; export default makeAPI ;