import { get } from 'lodash' ; import { TabbedAggResponseWriter } from './response_writer' ; import { TabifyBuckets } from './buckets' ; import { TabbedResponseWriterOptions } from './types' ; import { AggResponseBucket } from './types' ; import { AggGroupNames , IAggConfigs } from '../aggs' ; /**
 * Sets up the ResponseWriter and kicks off bucket collection.
 */ export function tabifyAggResponse ( aggConfigs , opensearchResponse , respOpts ? ) { /**
     * read an aggregation from a bucket, which *might* be found at key (if
     * the response came in object form), and will recurse down the aggregation
     * tree and will pass the read values to the ResponseWriter.
     */ function collectBucket ( aggs , write , bucket , key , aggScale ) { const column = write . columns . shift ( ) ; if ( column ) { const agg = column . aggConfig ; const aggInfo = agg . write ( aggs ) ; aggScale *= aggInfo . metricScale || 1 ; switch ( agg . type . type ) { case AggGroupNames . Buckets : const aggBucket = get ( bucket , agg . id ) ; const tabifyBuckets = new TabifyBuckets ( aggBucket , agg . params , respOpts ?. timeRange ) ; if ( tabifyBuckets . length ) { tabifyBuckets . forEach ( ( subBucket , tabifyBucketKey ) => { const bucketValue = agg . getKey ( subBucket , tabifyBucketKey ) ; const hasBucketValue = typeof bucketValue !== 'undefined' ; if ( hasBucketValue ) { write . bucketBuffer . push ( { id : column . id , value : bucketValue } ) ; } collectBucket ( aggs , write , subBucket , agg . getKey ( subBucket , tabifyBucketKey ) , aggScale ) ; if ( hasBucketValue ) { write . bucketBuffer . pop ( ) ; } } ) ; } else if ( respOpts ?. partialRows ) { write . columns . unshift ( column ) ; passEmptyBuckets ( aggs , write , bucket , key , aggScale ) ; write . columns . shift ( ) ; } else { write . row ( ) ; } break ; case AggGroupNames . Metrics : let value = agg . getValue ( bucket ) ; if ( aggScale !== 1 ) { value *= aggScale ; } write . metricBuffer . push ( { id : column . id , value } ) ; if ( ! write . columns . length ) { write . row ( ) ; } else { collectBucket ( aggs , write , bucket , key , aggScale ) ; } write . metricBuffer . pop ( ) ; break ; } write . columns . unshift ( column ) ; } } function passEmptyBuckets ( aggs , write , bucket , key , aggScale ) { const column = write . columns . shift ( ) ; if ( column ) { const agg = column . aggConfig ; switch ( agg . type . type ) { case AggGroupNames . Metrics : write . columns . unshift ( column ) ; collectBucket ( aggs , write , bucket , key , aggScale ) ; return ; case AggGroupNames . Buckets : passEmptyBuckets ( aggs , write , bucket , key , aggScale ) ; } write . columns . unshift ( column ) ; } } const write = new TabbedAggResponseWriter ( aggConfigs , respOpts || { } ) ; const topLevelBucket = { ... opensearchResponse . aggregations , doc_count : opensearchResponse . hits . total , } ; collectBucket ( aggConfigs , write , topLevelBucket , '' , 1 ) ; return write . response ( ) ; }