UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

1 lines 33.1 kB
{"version":3,"sources":["../../../packages/core/data/extension-broker/extension-broker.ts"],"names":[],"mappings":"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","file":"extension-broker.d.ts","sourcesContent":["import { from, Observable, of, Subject, zip } from 'rxjs';\r\nimport { filter, map, mergeMap, take, tap } from 'rxjs/operators';\r\nimport { LogLevel } from '../../diagnostics/log-level';\r\nimport { Logging } from '../../diagnostics/logging';\r\nimport { EnvironmentModuleEntryPoint, EnvironmentModuleEntryPointType, WorkerExtenderDefinition } from '../../manifest/environment-modules';\r\nimport {\r\n RpcExtensionBrokerRequest,\r\n RpcExtensionBrokerRequestResult,\r\n RpcExtensionBrokerResponseKey\r\n} from '../../rpc/extension-broker/rpc-extension-broker-model';\r\nimport { RpcExtensionBrokerModuleSubjectServer } from '../../rpc/extension-broker/rpc-extension-broker-module-request-subject-server';\r\nimport { RpcExtensionBrokerRequestClient } from '../../rpc/extension-broker/rpc-extension-broker-request-client';\r\nimport { DeferredData, Rpc } from '../../rpc/rpc';\r\nimport {\r\n ExtensionBrokerCallRequestPayload,\r\n ExtensionBrokerCreateRequestPayload,\r\n ExtensionBrokerDestroyRequestPayload,\r\n ExtensionBrokerEmitRequestPayload,\r\n ExtensionBrokerFindRequestPayload,\r\n ExtensionBrokerFulfillTargetRequestPayload,\r\n ExtensionBrokerListenRequestPayload,\r\n ExtensionBrokerMoveRequestPayload,\r\n ExtensionBrokerRequestPayload,\r\n ExtensionBrokerRunRequestPayload\r\n} from './model/extension-broker-request-payload';\r\nimport {\r\n ExtensionBrokerCallResponsePayload,\r\n ExtensionBrokerCreateResponsePayload,\r\n ExtensionBrokerDestroyResponsePayload,\r\n ExtensionBrokerFindResponsePayload,\r\n ExtensionBrokerFulfillTargetResponsePayload,\r\n ExtensionBrokerMoveResponsePayload,\r\n ExtensionBrokerResponsePayload,\r\n ExtensionBrokerRunResponsePayload,\r\n FulfillmentEntryPoints\r\n} from './model/extension-broker-response-payload';\r\nimport { ExtensionEntries } from './model/extension-entries';\r\nimport { DialogExtensionInstance, SnapInExtensionInstance, WorkerExtensionInstance } from './model/extension-instance';\r\nimport { ExtensionRect } from './model/extension-rect';\r\nimport { ExtensionSearchOptions } from './model/extension-search-options';\r\n\r\nexport abstract class ExtensionBrokerQuery {\r\n constructor(protected rpc: Rpc) { }\r\n protected watcher: Subject<RpcExtensionBrokerRequestResult>;\r\n\r\n public resultEmitter: Subject<ExtensionBrokerEmitRequestPayload>;\r\n\r\n public abstract getTargetExtensions(extensionTargetId: string): Observable<FulfillmentEntryPoints>;\r\n public abstract createSnapIn(entryPointId: string): Observable<SnapInExtensionInstance>;\r\n public abstract createWorker(entryPointId: string, extensionTarget?: string): Observable<WorkerExtensionInstance>;\r\n public abstract findWorker(searchOptions: ExtensionSearchOptions): Observable<WorkerExtensionInstance>;\r\n public abstract getExtensionEntryPointsByType(types: EnvironmentModuleEntryPointType[]): Observable<EnvironmentModuleEntryPoint[]>;\r\n public abstract runWorker(entryPointId: string, method: string, version: number, ...args: any[]): Observable<any>;\r\n public abstract startWorker(entryPointId: string, method: string, version: number, ...args: any[]): Observable<void>;\r\n public abstract createDialog(entryPointId: string): Observable<any>;\r\n public abstract showDialog(entryPointId: string, version: number, ...args: any[]): Observable<any>;\r\n public abstract callService(entryPointId: string, method: string, version: number, ...args: any[]): Observable<any>;\r\n public abstract request<T extends ExtensionBrokerResponsePayload>(payload: ExtensionBrokerRequestPayload): Observable<T>;\r\n\r\n /**\r\n * Handles rpc response messages from the extension host.\r\n * @param data the result of the extension host request\r\n */\r\n public onRpcResponse(data: RpcExtensionBrokerRequestResult): Promise<void> {\r\n this.watcher.next(data);\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * Calls a method on a extension instance and returns its result.\r\n * @param instanceId The instance id of the extension to call\r\n * @param method The method to call\r\n * @param version The version of the method to call\r\n * @param args The arguments to pass to the method\r\n * @returns an observable for the result of the call (may be null if method call is void)\r\n */\r\n protected call(instanceId: string, method: string, version: number, ...args: any[]): Observable<any> {\r\n const payload: ExtensionBrokerCallRequestPayload = {\r\n requestType: 'call',\r\n instanceId: instanceId,\r\n version: version,\r\n method: method,\r\n arguments: args,\r\n callType: 'worker'\r\n };\r\n return this.request(payload).pipe(map((response: ExtensionBrokerCallResponsePayload) => response.return));\r\n }\r\n\r\n /**\r\n * Destroys a extension instance\r\n * @param instanceId The instance id of the extension to destroy\r\n * @returns an observable for when the extension is destroyed\r\n */\r\n protected destroy(instanceId: string): Observable<ExtensionBrokerDestroyResponsePayload> {\r\n const payload: ExtensionBrokerDestroyRequestPayload = {\r\n requestType: 'destroy',\r\n instanceId: instanceId\r\n };\r\n return this.request(payload);\r\n }\r\n\r\n /**\r\n * Moves a extension instance\r\n * @param instanceId The instance id of the extension to destroy\r\n * @param rect The rectangular position to move the extension to (relative to the iframe)\r\n * @param zIndex the z index to move to, default is 1\r\n * @returns an observable for when the extension is destroyed\r\n */\r\n protected move(\r\n instanceId: string, rect: ExtensionRect, zIndex: number = 1): Observable<ExtensionBrokerMoveResponsePayload> {\r\n const payload: ExtensionBrokerMoveRequestPayload = {\r\n requestType: 'move',\r\n instanceId: instanceId,\r\n rect: rect,\r\n zIndex: zIndex\r\n };\r\n return this.request(payload);\r\n }\r\n}\r\n\r\n/**\r\n * Extension broker listener class\r\n * Register a listener without needed full extension broker service\r\n */\r\nexport class ExtensionBrokerListener {\r\n private static extensionBrokerModuleSubjectServer: RpcExtensionBrokerModuleSubjectServer;\r\n private static requestReceivedSubject: Subject<RpcExtensionBrokerRequest>;\r\n\r\n public static get requestReceived(): Observable<RpcExtensionBrokerRequest> {\r\n if (!ExtensionBrokerListener.requestReceivedSubject) {\r\n ExtensionBrokerListener.requestReceivedSubject = new Subject<RpcExtensionBrokerRequest>();\r\n }\r\n return ExtensionBrokerListener.requestReceivedSubject.asObservable();\r\n }\r\n\r\n public static initialize(rpc: Rpc) {\r\n // set up extension broker request channel\r\n if (!ExtensionBrokerListener.extensionBrokerModuleSubjectServer) {\r\n ExtensionBrokerListener.extensionBrokerModuleSubjectServer = new RpcExtensionBrokerModuleSubjectServer(rpc);\r\n ExtensionBrokerListener.extensionBrokerModuleSubjectServer.subject\r\n .subscribe(request => ExtensionBrokerListener.handleRpcRequest(request));\r\n }\r\n }\r\n\r\n private static handleRpcRequest(request: DeferredData<RpcExtensionBrokerRequest, void>) {\r\n Logging.log({\r\n level: LogLevel.Debug,\r\n message: `Extension broker request received: ${request}`,\r\n source: 'ExtensionBroker',\r\n params: request\r\n });\r\n\r\n request.deferred.resolve();\r\n if (ExtensionBrokerListener.requestReceivedSubject) {\r\n ExtensionBrokerListener.requestReceivedSubject.next(request.data);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Extension Broker Module Side Service.\r\n * Manages requests designated for other extensions through the shell using RPC\r\n */\r\nexport class ExtensionBroker extends ExtensionBrokerQuery {\r\n\r\n /**\r\n * The source name to use for logging\r\n */\r\n protected get logSourceName() {\r\n return 'ExtensionBroker';\r\n }\r\n\r\n /**\r\n * Initializes a new instance of the Extension Broker class\r\n * @param rpc The rpc to use to communicate with the shell\r\n */\r\n constructor(rpc: Rpc) {\r\n super(rpc);\r\n // set up extension broker response channel\r\n this.watcher = new Subject<RpcExtensionBrokerRequestResult>();\r\n this.rpc.register(RpcExtensionBrokerResponseKey.command, this.onRpcResponse.bind(this));\r\n\r\n // set up extension broker request channel\r\n ExtensionBrokerListener.initialize(rpc);\r\n\r\n // hook up emit event pipeline\r\n ExtensionBrokerListener.requestReceived.pipe(\r\n filter(request => request.payload && request.payload.requestType === 'emit')\r\n ).subscribe(request => this.onEmitReceived(request));\r\n this.resultEmitter = new Subject<ExtensionBrokerEmitRequestPayload>();\r\n }\r\n\r\n /**\r\n * Occurs when an emit request is received from shell\r\n */\r\n private onEmitReceived(request: RpcExtensionBrokerRequest): void {\r\n Logging.log({\r\n level: LogLevel.Debug,\r\n message: `Emit request received`,\r\n source: this.logSourceName,\r\n params: request\r\n });\r\n const payload = <ExtensionBrokerEmitRequestPayload>request.payload;\r\n this.resultEmitter.next(payload);\r\n }\r\n\r\n /**\r\n * Gets the entry point ids for all the extensions that fulfill an extension targets contract\r\n * In some cases, as specified by the extension target, the shell may ask the user to select a preferred\r\n * extension that fulfills the target contract. Returning only the 1 entry point id.\r\n * @param extensionTargetId The id of the extension target\r\n * @return An observable for the entry point ids of the extensions that fulfill an extension targets contract.\r\n */\r\n public getTargetExtensions(extensionTargetId: string): Observable<FulfillmentEntryPoints> {\r\n const payload: ExtensionBrokerFulfillTargetRequestPayload = {\r\n requestType: 'fulfill',\r\n extensionTargetId: extensionTargetId\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerFulfillTargetResponsePayload) => {\r\n return response.fulfillment;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Creates a SnapIn instance given its entry point id.\r\n * This instance is tied to the calling extension and will close when destroy is called or the calling extension is destroyed.\r\n * @param entryPointId The id of the worker to create\r\n */\r\n public createSnapIn(entryPointId: string): Observable<SnapInExtensionInstance> {\r\n const payload: ExtensionBrokerCreateRequestPayload = {\r\n requestType: 'create',\r\n entryPointId: entryPointId\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerCreateResponsePayload) => {\r\n const instance: SnapInExtensionInstance = {\r\n instanceId: response.instanceId,\r\n call: (method: string, version: number, ...args: any[]) => this.call(response.instanceId, method, version, ...args),\r\n destroy: () => this.destroy(response.instanceId).pipe(map(MsftSme.noop)),\r\n move: (rect: ExtensionRect, zIndex?: number) =>\r\n this.move(response.instanceId, rect, zIndex).pipe(map(MsftSme.noop)),\r\n listen: (eventType: string) => this.listen(eventType, response.instanceId)\r\n };\r\n\r\n return instance;\r\n }\r\n ));\r\n }\r\n\r\n /**\r\n * Finds a worker given either its entryPointId or instanceId\r\n * @param searchOptions The search options for finding a worker instance\r\n */\r\n public findWorker(searchOptions: ExtensionSearchOptions): Observable<WorkerExtensionInstance> {\r\n // if search will always result in no worker, just return no worker.\r\n if (MsftSme.isNullOrUndefined(searchOptions)\r\n || (MsftSme.isNullOrUndefined(searchOptions.entryPointId)\r\n && MsftSme.isNullOrUndefined(searchOptions.instanceId))) {\r\n return of(null);\r\n }\r\n const payload: ExtensionBrokerFindRequestPayload = {\r\n requestType: 'find',\r\n searchOptions: searchOptions\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerFindResponsePayload) => {\r\n if (!response.found) {\r\n return null;\r\n }\r\n const instance: WorkerExtensionInstance = {\r\n instanceId: response.instanceId,\r\n extenderDefinition: <WorkerExtenderDefinition>response.extenderDefinition,\r\n contract: response.contract,\r\n call: (method: string, version: number, ...args: any[]) => this.call(response.instanceId, method, version, ...args),\r\n destroy: () => this.destroy(response.instanceId).pipe(map(MsftSme.noop)),\r\n listen: (eventType: string) => this.listen(eventType, response.instanceId)\r\n };\r\n return instance;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Finds extensions by search condition.\r\n * @param searchOptions The search options for finding manifest entry points that meet the condition.\r\n */\r\n public findEntriesByCondition(searchOptions: ExtensionSearchOptions): Observable<ExtensionEntries> {\r\n // set of search options must meet.\r\n if (MsftSme.isNullOrUndefined(searchOptions)\r\n || !MsftSme.isNullOrUndefined(searchOptions.entryPointId)\r\n || !MsftSme.isNullOrUndefined(searchOptions.instanceId)\r\n || searchOptions.createIfNotFound\r\n || (searchOptions.extensionTypes == null || searchOptions.extensionTypes.length === 0)\r\n || MsftSme.isNullOrUndefined(searchOptions.condition)) {\r\n throw new Error('Argument error for \\\"searchOptions\\\" on findEntriesByCondition() function');\r\n }\r\n const payload: ExtensionBrokerFindRequestPayload = {\r\n requestType: 'find',\r\n searchOptions: searchOptions\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerFindResponsePayload) => {\r\n const conditionValidated = searchOptions.condition.validationRequired;\r\n let entryPoints: EnvironmentModuleEntryPoint[] = [];\r\n if (response.found) {\r\n entryPoints = response.entryPoints;\r\n }\r\n\r\n return <ExtensionEntries>{ entryPoints, conditionValidated };\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * return all registered entry points by type\r\n * @param types entry point types to return\r\n */\r\n public getExtensionEntryPointsByType(types: EnvironmentModuleEntryPointType[]): Observable<EnvironmentModuleEntryPoint[]> {\r\n if (MsftSme.isNullOrUndefined(types)) {\r\n return of(null);\r\n }\r\n const payload: ExtensionBrokerFindRequestPayload = {\r\n requestType: 'find',\r\n searchOptions: { extensionTypes: types }\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerFindResponsePayload) => {\r\n if (!response.found) {\r\n return null;\r\n }\r\n\r\n return response.entryPoints;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Creates a worker instance given its entry point id.\r\n * This instance is tied to the calling extension and will close when destroy is called or the calling extension is destroyed.\r\n * @param entryPointId The id of the worker to create\r\n */\r\n public createWorker(entryPointId: string, extensionTarget?: string): Observable<WorkerExtensionInstance> {\r\n const payload: ExtensionBrokerCreateRequestPayload = {\r\n requestType: 'create',\r\n entryPointId: entryPointId,\r\n extensionTarget: extensionTarget\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerCreateResponsePayload) => {\r\n const instance: WorkerExtensionInstance = {\r\n instanceId: response.instanceId,\r\n extenderDefinition: <WorkerExtenderDefinition>response.extenderDefinition,\r\n contract: response.contract,\r\n call: (method: string, version: number, ...args: any[]) => this.call(response.instanceId, method, version, ...args),\r\n destroy: () => this.destroy(response.instanceId).pipe(map(MsftSme.noop)),\r\n listen: (eventType: string) => this.listen(eventType, response.instanceId)\r\n };\r\n return instance;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * subscribe to results emission for specific action\r\n */\r\n public listen(eventType: string, instanceId: string): Observable<any> {\r\n // send request to shell to add to database\r\n // return result emitter filtered by type and instance\r\n const payload: ExtensionBrokerListenRequestPayload = {\r\n requestType: 'listen',\r\n instanceId,\r\n eventType\r\n };\r\n return this.request(payload).pipe(\r\n mergeMap(() => this.resultEmitter.asObservable()),\r\n filter(result => result.instanceId === instanceId && result.eventType === eventType)\r\n );\r\n }\r\n\r\n /**\r\n * Runs a worker instance and returns the result of one method. After which the worker is destroyed.\r\n * @param entryPointId The id of the worker to create\r\n * @param method The method to call\r\n * @param version The version of the method to call\r\n * @param args The arguments to pass to the method\r\n * @returns an observable for the result of the worker.\r\n */\r\n public runWorker(entryPointId: string, method: string, version: number, ...args: any[]): Observable<any> {\r\n const payload: ExtensionBrokerRunRequestPayload = {\r\n requestType: 'run',\r\n entryPointId: entryPointId,\r\n version: version,\r\n method: method,\r\n arguments: args\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerRunResponsePayload) => {\r\n return response.return;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Runs a worker instance with no association to the calling extension.\r\n * The worker will run its own workflow until it is finished\r\n * @param entryPointId The id of the worker to create\r\n * @param method The method to call\r\n * @param version The version of the method to call\r\n * @param args The arguments to pass to the method\r\n * @returns an observable fro the creation of the worker.\r\n */\r\n public startWorker(entryPointId: string, method: string, version: number, ...args: any[]): Observable<void> {\r\n const payload: ExtensionBrokerRunRequestPayload = {\r\n requestType: 'run',\r\n expectReturn: false,\r\n entryPointId: entryPointId,\r\n version: version,\r\n method: method,\r\n arguments: args\r\n };\r\n return this.request(payload).pipe(map(MsftSme.noop));\r\n }\r\n\r\n /**\r\n * Runs a dialog instance and returns its result. After which the dialog is destroyed.\r\n * @param entryPointId The id of the dialog to create\r\n * @param version The version of the dialog to call\r\n * @param args The arguments to pass to the dialog\r\n * @returns an observable for the result of the dialog.\r\n */\r\n public createDialog(entryPointId: string): Observable<any> {\r\n const payload: ExtensionBrokerCreateRequestPayload = {\r\n requestType: 'create',\r\n entryPointId: entryPointId\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerCreateResponsePayload) => {\r\n const instance: DialogExtensionInstance = {\r\n instanceId: response.instanceId,\r\n extenderDefinition: <WorkerExtenderDefinition>response.extenderDefinition,\r\n contract: response.contract,\r\n show: (version: number, ...args: any[]) => this.show(response.instanceId, version, ...args),\r\n hide: () => this.destroy(response.instanceId).pipe(map(MsftSme.noop)),\r\n listen: (eventType: string) => this.listen(eventType, response.instanceId)\r\n };\r\n return instance;\r\n })\r\n );\r\n\r\n }\r\n\r\n /**\r\n * Runs a dialog instance and returns its result. After which the dialog is destroyed.\r\n * @param entryPointId The id of the dialog to create\r\n * @param version The version of the dialog to call\r\n * @param args The arguments to pass to the dialog\r\n * @returns an observable for the result of the dialog.\r\n */\r\n public showDialog(entryPointId: string, version: number, ...args: any[]): Observable<any> {\r\n const payload: ExtensionBrokerRunRequestPayload = {\r\n requestType: 'run',\r\n entryPointId: entryPointId,\r\n version: version,\r\n method: 'show',\r\n arguments: args\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerRunResponsePayload) => {\r\n return response.return;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Runs a dialog instance and returns its result. After which the dialog is destroyed.\r\n * @param instanceId The id of the extension to show\r\n * @param version The version of the extension tp show\r\n * @param args The arguments to pass to the extension\r\n * @returns an observable for the result of the dialog.\r\n */\r\n public show(instanceId: string, version: number, ...args: any[]): Observable<any> {\r\n const payload: ExtensionBrokerCallRequestPayload = {\r\n requestType: 'call',\r\n instanceId: instanceId,\r\n version: version,\r\n method: 'show',\r\n arguments: args,\r\n callType: 'component'\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerRunResponsePayload) => {\r\n return response.return;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Emit a result to listeners subscribed to the given eventType and instanceId\r\n * @param instanceId The instance Id of the component emitting the result\r\n * @param eventType the type of event being emitted, can be any string like \"output\", \"validation\", \"changes\"\r\n * so listeners can subscribe to specific event streams. listeners must be aware of chosen eventType\r\n * @param result the result to be sent to event listeners\r\n */\r\n public emitResult<T>(instanceId: string, eventType: string, result: T): Observable<ExtensionBrokerResponsePayload> {\r\n const payload: ExtensionBrokerEmitRequestPayload = {\r\n requestType: 'emit',\r\n instanceId: instanceId,\r\n eventType: eventType,\r\n data: result\r\n };\r\n return this.request(payload);\r\n }\r\n\r\n /**\r\n * Calls a method on a service extension\r\n * @param entryPointId The id of the service to call\r\n * @param method The method to call\r\n * @param version The version of the method to call\r\n * @param args The arguments to pass to the method\r\n * @returns an observable for the result of the service method.\r\n */\r\n public callService(entryPointId: string, method: string, version: number, ...args: any[]): Observable<any> {\r\n const payload: ExtensionBrokerCallRequestPayload = {\r\n requestType: 'call',\r\n instanceId: entryPointId,\r\n version: version,\r\n method: method,\r\n arguments: args,\r\n callType: 'service'\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerCallResponsePayload) => {\r\n return response.return;\r\n })\r\n );\r\n }\r\n\r\n public destroyRequested(entryPointId: string, version: number, args?: any[]) {\r\n const payload: ExtensionBrokerCallRequestPayload = {\r\n requestType: 'call',\r\n instanceId: entryPointId,\r\n version: version,\r\n method: 'destroyRequested',\r\n arguments: args,\r\n callType: 'component'\r\n };\r\n return this.request(payload).pipe(\r\n map((response: ExtensionBrokerCallResponsePayload) => {\r\n return response.return;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Makes an extension broker request via the RPC\r\n * @param requestType The @see RpcExtensionBrokerRequestType.\r\n * @param payload The payload for this message. Depends on requestType.\r\n * @returns An observable for the response message from the shell\r\n */\r\n public request<T extends ExtensionBrokerResponsePayload>(payload: ExtensionBrokerRequestPayload): Observable<T> {\r\n const request: RpcExtensionBrokerRequest = {\r\n requestId: MsftSme.newGuid(),\r\n payload: payload\r\n };\r\n Logging.log({\r\n level: LogLevel.Debug,\r\n message: `Sending request to Extension Broker Service: ${request.requestId}`,\r\n source: 'ExtensionBroker',\r\n params: {\r\n request: request\r\n }\r\n });\r\n return zip(\r\n // wait for our request promise to be fulfilled\r\n from(RpcExtensionBrokerRequestClient.extensionBrokerRequest(this.rpc, request)).pipe(\r\n tap(() => {\r\n Logging.log({\r\n level: LogLevel.Debug,\r\n message: `Request verified received from Extension Broker Shell Service: ${request.requestId}`,\r\n source: 'ExtensionBroker',\r\n params: {\r\n request: request\r\n }\r\n });\r\n })\r\n ),\r\n // wait for our response to come in via RPC, this may happen anytime after the request is sent,\r\n // but not necessarily after its promise is resolved\r\n this.watcher.pipe(filter((result) => {\r\n const isMatch = result.requestId === request.requestId;\r\n Logging.log({\r\n level: LogLevel.Debug,\r\n message: `Checking potential response from Extension Broker Shell Service: ${result.requestId} === ${request.requestId} => ${isMatch}`,\r\n source: 'ExtensionBroker',\r\n params: {\r\n request: request,\r\n potentialResponse: result\r\n }\r\n });\r\n return isMatch;\r\n }))\r\n ).pipe(\r\n take(1),\r\n map(([_, result]) => {\r\n if (!MsftSme.isNullOrUndefined(result)) {\r\n if (!MsftSme.isNullOrUndefined(result.payload)) {\r\n return result.payload;\r\n } else if (!MsftSme.isNullOrUndefined(result.error)) {\r\n throw result.error;\r\n }\r\n }\r\n throw new Error('Unexpected Response from Extension Broker RPC Request');\r\n })\r\n );\r\n }\r\n}\r\n"]}