import { Subscription } from 'rxjs' ; import { IUiSettingsClient } from 'src/core/public' ; import { ExpressionsServiceSetup } from 'src/plugins/expressions/common' ; import { FieldFormatsStart } from '../../field_formats' ; import { getForceNow } from '../../query/timefilter/lib/get_force_now' ; import { calculateBounds , TimeRange } from '../../../common' ; import { aggsRequiredUiSettings , AggsCommonStartDependencies , AggsCommonService , AggConfigs , AggTypesDependencies , } from '../../../common/search/aggs' ; import { AggsSetup , AggsStart } from './types' ; internal export function createGetConfig ( uiSettings , requiredSettings , subscriptions ) { const settingsCache = { } ; requiredSettings . forEach ( ( setting ) => { subscriptions . push ( uiSettings . get$ ( setting ) . subscribe ( ( value ) => { settingsCache [ setting ] = value ; } ) ) ; } ) ; return ( key ) => settingsCache [ key ] ; } internal export interface AggsSetupDependencies { registerFunction : ExpressionsServiceSetup [ 'registerFunction' ] ; uiSettings : IUiSettingsClient ; } internal export interface AggsStartDependencies { fieldFormats : FieldFormatsStart ; uiSettings : IUiSettingsClient ; } /**
 * The aggs service provides a means of modeling and manipulating the various
 * OpenSearch aggregations supported by OpenSearch Dashboards, providing the ability to
 * output the correct DSL when you are ready to send your request to OpenSearch.
 */ export class AggsService { private readonly aggsCommonService = new AggsCommonService ( ) ; private readonly initializedAggTypes = new Map ( ) ; private getConfig ? : AggsCommonStartDependencies [ 'getConfig' ] ; private subscriptions : Subscription [ ] = [ ] ; /**
     * getForceNow uses window.location, so we must have a separate implementation
     * of calculateBounds on the client and the server.
     */ private calculateBounds = ( timeRange ) => calculateBounds ( timeRange , { forceNow : getForceNow ( ) } ) ; public setup ( { registerFunction , uiSettings } ) { this . getConfig = createGetConfig ( uiSettings , aggsRequiredUiSettings , this . subscriptions ) ; return this . aggsCommonService . setup ( { registerFunction } ) ; } public start ( { fieldFormats , uiSettings } ) { const { calculateAutoTimeExpression , types } = this . aggsCommonService . start ( { getConfig : this . getConfig ! , } ) ; const aggTypesDependencies = { calculateBounds : this . calculateBounds , getConfig : this . getConfig ! , getFieldFormatsStart : ( ) => ( { deserialize : fieldFormats . deserialize , getDefaultInstance : fieldFormats . getDefaultInstance , } ) , isDefaultTimezone : ( ) => uiSettings . isDefault ( 'dateFormat:tz' ) , } ; types . getAll ( ) . buckets . forEach ( ( type ) => { const agg = type ( aggTypesDependencies ) ; this . initializedAggTypes . set ( agg . name , agg ) ; } ) ; types . getAll ( ) . metrics . forEach ( ( type ) => { const agg = type ( aggTypesDependencies ) ; this . initializedAggTypes . set ( agg . name , agg ) ; } ) ; const typesRegistry = { get : ( name ) => { return this . initializedAggTypes . get ( name ) ; } , getAll : ( ) => { return { buckets : Array . from ( this . initializedAggTypes . values ( ) ) . filter ( ( agg ) => agg . type === 'buckets' ) , metrics : Array . from ( this . initializedAggTypes . values ( ) ) . filter ( ( agg ) => agg . type === 'metrics' ) , } ; } , } ; return { calculateAutoTimeExpression , createAggConfigs : ( indexPattern , configStates = [ ] , schemas ) => { return new AggConfigs ( indexPattern , configStates , { typesRegistry } ) ; } , types : typesRegistry , } ; } public stop ( ) { this . subscriptions . forEach ( ( s ) => s . unsubscribe ( ) ) ; this . subscriptions = [ ] ; } }