import { Observable } from 'rxjs' ; import { first } from 'rxjs/operators' ; import { mapToObject } from '@osd/std' ; import { CoreService } from '../../types' ; import { CoreContext } from '../core_context' ; import { Logger } from '../logging' ; import { SavedObjectsClientContract } from '../saved_objects/types' ; import { InternalSavedObjectsServiceSetup } from '../saved_objects' ; import { InternalHttpServiceSetup } from '../http' ; import { UiSettingsConfigType , config as uiConfigDefinition } from './ui_settings_config' ; import { UiSettingsClient } from './ui_settings_client' ; import { InternalUiSettingsServiceSetup , InternalUiSettingsServiceStart , UiSettingsParams , } from './types' ; import { uiSettingsType } from './saved_objects' ; import { registerRoutes } from './routes' ; import { getCoreSettings } from './settings' ; export interface SetupDeps { http : InternalHttpServiceSetup ; savedObjects : InternalSavedObjectsServiceSetup ; } internal export class UiSettingsService implements CoreService < InternalUiSettingsServiceSetup , InternalUiSettingsServiceStart > { private readonly log : Logger ; private readonly config$ : Observable < UiSettingsConfigType > ; private readonly uiSettingsDefaults = new Map < string , UiSettingsParams > ( ) ; private overrides : Record < string , any > = { } ; constructor ( private readonly coreContext ) { this . log = coreContext . logger . get ( 'ui-settings-service' ) ; this . config$ = coreContext . configService . atPath < UiSettingsConfigType > ( uiConfigDefinition . path ) ; } public async setup ( { http , savedObjects } ) { this . log . debug ( 'Setting up ui settings service' ) ; savedObjects . registerType ( uiSettingsType ) ; registerRoutes ( http . createRouter ( '' ) ) ; this . register ( getCoreSettings ( ) ) ; const config = await this . config$ . pipe ( first ( ) ) . toPromise ( ) ; this . overrides = config . overrides ; return { register : this . register . bind ( this ) , } ; } public async start ( ) { this . validatesDefinitions ( ) ; this . validatesOverrides ( ) ; return { asScopedToClient : this . getScopedClientFactory ( ) , } ; } public async stop ( ) { } private getScopedClientFactory ( ) { const { version , buildNum } = this . coreContext . env . packageInfo ; return ( savedObjectsClient ) => new UiSettingsClient ( { type : 'config' , id : version , buildNum , savedObjectsClient , defaults : mapToObject ( this . uiSettingsDefaults ) , overrides : this . overrides , log : this . log , } ) ; } private register ( settings = { } ) { Object . entries ( settings ) . forEach ( ( [ key , value ] ) => { if ( this . uiSettingsDefaults . has ( key ) ) { throw new Error ( `uiSettings for the key [${ key }] has been already registered` ) ; } this . uiSettingsDefaults . set ( key , value ) ; } ) ; } private validatesDefinitions ( ) { for ( const [ key , definition ] of this . uiSettingsDefaults ) { if ( definition . schema ) { definition . schema . validate ( definition . value , { } , `ui settings defaults [${ key }]` ) ; } } } private validatesOverrides ( ) { for ( const [ key , value ] of Object . entries ( this . overrides ) ) { const definition = this . uiSettingsDefaults . get ( key ) ; if ( definition ?. schema ) { definition . schema . validate ( value , { } , `ui settings overrides [${ key }]` ) ; } } } }