import { from , merge } from 'rxjs' ; import { catchError , filter , map , mergeMap , concatMap , shareReplay , toArray } from 'rxjs/operators' ; import { CoreContext } from '../../core_context' ; import { Logger } from '../../logging' ; import { PluginWrapper } from '../plugin' ; import { createPluginInitializerContext , InstanceInfo } from '../plugin_context' ; import { PluginsConfig } from '../plugins_config' ; import { PluginDiscoveryError } from './plugin_discovery_error' ; import { parseManifest } from './plugin_manifest_parser' ; import { scanPluginSearchPaths } from './scan_plugin_search_paths' ; param config param coreContext internal export function discover ( config , coreContext , instanceInfo ) { const log = coreContext . logger . get ( 'plugins-discovery' ) ; log . debug ( 'Discovering plugins...' ) ; if ( config . additionalPluginPaths . length && coreContext . env . mode . dev ) { log . warn ( `Explicit plugin paths [${ config . additionalPluginPaths }] should only be used in development. Relative imports may not work properly in production.` ) ; } const discoveryResults$ = merge ( from ( config . additionalPluginPaths ) , scanPluginSearchPaths ( config . pluginSearchPaths , log ) ) . pipe ( toArray ( ) , mergeMap ( ( pathAndErrors ) => { return pathAndErrors . sort ( ( a , b ) => { const pa = typeof a === 'string' ? a : a . path ; const pb = typeof b === 'string' ? b : b . path ; return pa < pb ? - 1 : pa > pb ? 1 : 0 ; } ) ; } ) , concatMap ( ( pluginPathOrError ) => { return typeof pluginPathOrError === 'string' ? createPlugin$ ( pluginPathOrError , log , coreContext , instanceInfo ) : [ pluginPathOrError ] ; } ) , shareReplay ( ) ) ; return { plugin$ : discoveryResults$ . pipe ( filter ( ( entry ) : entry is PluginWrapper => entry instanceof PluginWrapper ) ) , error$ : discoveryResults$ . pipe ( filter ( ( entry ) : entry is PluginDiscoveryError => ! ( entry instanceof PluginWrapper ) ) ) , } ; } param path param log param coreContext function createPlugin$ ( path , log , coreContext , instanceInfo ) { return from ( parseManifest ( path , coreContext . env . packageInfo ) ) . pipe ( map ( ( manifest ) => { log . debug ( `Successfully discovered plugin "${ manifest . id }" at "${ path }"` ) ; const opaqueId = Symbol ( manifest . id ) ; return new PluginWrapper ( { path , manifest , opaqueId , initializerContext : createPluginInitializerContext ( coreContext , opaqueId , manifest , instanceInfo ) , } ) ; } ) , catchError ( ( err ) => [ err ] ) ) ; }