{"version":3,"sources":["../../../packages/core/notification/powershell-notification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,MAAM,CAAC;AAI/C,OAAO,EAAE,cAAc,EAAe,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAMvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAsB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,iBAAiB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC;IACtG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAwB;IACpD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAY;IACjC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAe;IACvC,OAAO,CAAC,eAAe,CAA0E;WAGnF,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC,GAAG,OAAO;WAIjG,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC,GAAG,OAAO;WAIvF,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC,GAAG,OAAO;WAI3F,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,yBAAyB,GAAE,mBAAmB,CAAC,GAAG,OAAO;WAI1F,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,yBAAyB,GAAE,mBAAmB,CAAC,GAAG,OAAO;WAIrF,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC,GAAG,OAAO;IAIxG;;OAEG;gBACS,UAAU,EAAE,MAAM;IAI9B;;OAEG;IACH,IAAW,OAAO,IAAI,UAAU,CAAC,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC,CAAC,CAE/F;IAED;;;;;;;;;OASG;IACI,MAAM,CACT,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,GAAG,EACb,kBAAkB,CAAC,EAAE,kBAAkB,EACvC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,IAAI,GAAG,UAAU,CAAC,cAAc,CAAC;IAkGlF;;OAEG;IACI,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC;IAUjC;;OAEG;IACI,YAAY,IAAI,IAAI;IAU3B;;;;;OAKG;IACI,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,GAAG,mBAAmB,CAAC;IAI7F;;;;OAIG;IACH,SAAS,CAAC,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,yBAAyB,GAAG,mBAAmB,CAAC,GAAG,IAAI;IAI3G;;;;OAIG;IACH,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAqB/C,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,kBAAkB;CAI7B","file":"powershell-notification.d.ts","sourcesContent":["import { Observable, of, Subject } from 'rxjs';\r\nimport { AjaxError } from 'rxjs/ajax';\r\nimport { catchError, map } from 'rxjs/operators';\r\nimport { Net } from '../data/net';\r\nimport { NodeConnection, NodeRequest, NodeRequestOptions } from '../data/node-connection';\r\nimport { PowerShellCommand } from '../data/powershell';\r\nimport { LogLevel } from '../diagnostics/log-level';\r\nimport { Logging } from '../diagnostics/logging';\r\nimport { SmeWebTelemetry } from '../diagnostics/sme-web-telemetry';\r\nimport { TelemetryEventStates } from '../diagnostics/sme-web-telemetry-models';\r\nimport { Strings } from '../generated/strings';\r\nimport { NotificationMessage } from './notification-message';\r\nimport { NotificationState } from './notification-state';\r\nimport { SocketMessage, SocketMessageFlags, SocketSignalR } from './socket-signalr';\r\nimport { WorkItemResult } from './work-item-request';\r\n\r\n/**\r\n * PowerShell Submit result object.\r\n */\r\nexport interface PowerShellSubmitResult {\r\n    id: string;\r\n    completed: boolean;\r\n    error: any;\r\n    state: NotificationState;\r\n}\r\n\r\n/**\r\n * Powershell work item message.\r\n */\r\nexport interface PowerShellWorkItemMessage {\r\n    sessionId?: string;\r\n    completed?: string; // True, False\r\n    results?: any[];\r\n    progress?: any[];\r\n    errors?: any[];\r\n    exception?: string;\r\n}\r\n\r\n/**\r\n * The PowerShell script based notification class.\r\n */\r\nexport class PowerShellNotification extends SocketSignalR<PowerShellWorkItemMessage | NotificationMessage> {\r\n    private static connectionUrl = '/api/notifications';\r\n    private static notify = 'Notify';\r\n    private static subscribe = 'Subscribe';\r\n    private subjectInternal: Subject<SocketMessage<PowerShellWorkItemMessage | NotificationMessage>>;\r\n\r\n    /* tslint:disable:no-bitwise */\r\n    public static hasConnectionError(item: SocketMessage<PowerShellWorkItemMessage | NotificationMessage>): boolean {\r\n        return (item.type & SocketMessageFlags.ConnectionError) === SocketMessageFlags.ConnectionError;\r\n    }\r\n\r\n    public static hasError(item: SocketMessage<PowerShellWorkItemMessage | NotificationMessage>): boolean {\r\n        return (item.type & SocketMessageFlags.Error) === SocketMessageFlags.Error;\r\n    }\r\n\r\n    public static hasException(item: SocketMessage<PowerShellWorkItemMessage | NotificationMessage>): boolean {\r\n        return (item.type & SocketMessageFlags.Exception) === SocketMessageFlags.Exception;\r\n    }\r\n\r\n    public static hasCompleted(item: SocketMessage<PowerShellWorkItemMessage| NotificationMessage>): boolean {\r\n        return (item.type & SocketMessageFlags.Completed) === SocketMessageFlags.Completed;\r\n    }\r\n\r\n    public static hasData(item: SocketMessage<PowerShellWorkItemMessage| NotificationMessage>): boolean {\r\n        return (item.type & SocketMessageFlags.Data) === SocketMessageFlags.Data;\r\n    }\r\n\r\n    public static hasProgress(item: SocketMessage<PowerShellWorkItemMessage | NotificationMessage>): boolean {\r\n        return (item.type & SocketMessageFlags.Progress) === SocketMessageFlags.Progress;\r\n    }\r\n\r\n    /**\r\n     * Initializes a new instance of the GatewaySocket class.\r\n     */\r\n    constructor(gatewayUrl: string) {\r\n        super(gatewayUrl, PowerShellNotification.connectionUrl);\r\n    }\r\n\r\n    /**\r\n     * Gets the subject observable to get notifications.\r\n     */\r\n    public get subject(): Observable<SocketMessage<PowerShellWorkItemMessage | NotificationMessage>> {\r\n        return this.subjectInternal.asObservable();\r\n    }\r\n\r\n    /**\r\n     * Submit PowerShell command as a work item.\r\n     *\r\n     * @param nodeConnection The node connection.\r\n     * @param command The PowerShell command.\r\n     * @param metadata The meta data.\r\n     * @param nodeRequestOptions The node request options.\r\n     * @param create The callback to create new notification.\r\n     * @return Observable the observable of initial powershell query result.\r\n     */\r\n    public submit(\r\n        nodeConnection: NodeConnection,\r\n        nodeName: string,\r\n        command: PowerShellCommand,\r\n        metadata: any,\r\n        nodeRequestOptions?: NodeRequestOptions,\r\n        create?: (result: PowerShellSubmitResult) => void): Observable<WorkItemResult> {\r\n        // For a non-powershell long running task (eg: azure site recovery setup):\r\n        // The 'command' parameter is null.\r\n        // The metadata.id is the workitem id generated by a gateway api.\r\n        if (!command && metadata.id) {\r\n            const result = <PowerShellSubmitResult>{\r\n                id: metadata.id,\r\n                completed: false,\r\n                error: null,\r\n                state: NotificationState.Started\r\n            };\r\n            if (create) {\r\n                create(result);\r\n            }\r\n\r\n            this.subscribeSession(metadata.id);\r\n            return of(<WorkItemResult>{ id: metadata.id, state: NotificationState.Started, error: null });\r\n        }\r\n\r\n        const data: any = Net.createPropertiesJSONString({\r\n            ...command,\r\n            useInProcRunspace: nodeRequestOptions.useInProcRunspace,\r\n            ...{ metadata: metadata } });\r\n        return nodeConnection.post(nodeName, Net.powerShellApiInvokeCommand, data, <NodeRequest>nodeRequestOptions)\r\n            .pipe(\r\n                catchError((error: AjaxError) => {\r\n                    SmeWebTelemetry.tracePowershellEvent(command, TelemetryEventStates.Error,\r\n                        {response: error.response});\r\n\r\n                    const result = <PowerShellSubmitResult>{\r\n                        id: MsftSme.newGuid(),\r\n                        completed: true,\r\n                        error: { message: Net.getErrorMessage(error) },\r\n                        state: NotificationState.Error\r\n                    };\r\n                    if (create) {\r\n                        create(result);\r\n                    }\r\n\r\n                    return of(<WorkItemResult>{ id: result.id, state: result.state, error: result.error });\r\n                }),\r\n                map((response: any) => {\r\n                    const completed = response.completed === 'True';\r\n\r\n                    if (response.id) {\r\n                        // sending back the client for the error.\r\n                        return <WorkItemResult>response;\r\n                    }\r\n\r\n                    let error: any = null;\r\n                    if (response.errors && response.errors.length > 0) {\r\n                        const errorObj: any = MsftSme.first(response.errors);\r\n                        error = { message: errorObj.message };\r\n\r\n                        SmeWebTelemetry.tracePowershellEvent(command,\r\n                            TelemetryEventStates.Error,\r\n                            {response: response});\r\n                    }\r\n\r\n                    const result = <PowerShellSubmitResult>{\r\n                        id: response.sessionId,\r\n                        completed: completed,\r\n                        error: error,\r\n                        state: completed ?\r\n                            (response.errors ? NotificationState.Error : NotificationState.Success)\r\n                            : NotificationState.Started\r\n                    };\r\n\r\n                    if (result.state === NotificationState.Success) {\r\n                        result.error = response.results[0];\r\n                    }\r\n\r\n                    if (create) {\r\n                        create(result);\r\n                    }\r\n\r\n                    if (!result.completed) {\r\n                        this.subscribeSession(response.sessionId);\r\n\r\n                        // store ID here to correlate command with the gateway notification later\r\n                        const powershellCommandId = response.id ? response.id : response.sessionId;\r\n                        SmeWebTelemetry.addPowershellId(powershellCommandId, command);\r\n                    }\r\n\r\n                    this.processPowerShellData(response);\r\n\r\n                    // sending back the client.\r\n                    const workItemResult = <WorkItemResult>{ id: result.id, state: result.state, error: error };\r\n\r\n                    // passing in the results as object of the workItemResult\r\n                    if (response.results) {\r\n                        workItemResult.object = response.results;\r\n                    }\r\n\r\n                    return workItemResult;\r\n                }));\r\n    }\r\n\r\n    /**\r\n     * Initialize to subscribe the web socket connection.\r\n     */\r\n    public initialize(): Promise<any> {\r\n        if (this.subjectInternal) {\r\n            this.subjectInternal.complete();\r\n        }\r\n\r\n        this.subjectInternal = new Subject<SocketMessage<PowerShellWorkItemMessage | NotificationMessage>>();\r\n        this.subscribe(PowerShellNotification.notify);\r\n        return this.start();\r\n    }\r\n\r\n    /**\r\n     * Uninitialize to subscribe the web socket connection.\r\n     */\r\n    public uninitialize(): void {\r\n        if (this.subjectInternal) {\r\n            this.subjectInternal.complete();\r\n            this.subjectInternal = null;\r\n        }\r\n\r\n        this.unsubscribe(PowerShellNotification.notify);\r\n        this.stop();\r\n    }\r\n\r\n    /**\r\n     * Invoke subscribe method to a  session.\r\n     *\r\n     * @param id the session ID of work item.\r\n     * @return Promise the promise object.\r\n     */\r\n    public subscribeSession(id: string): Promise<PowerShellWorkItemMessage | NotificationMessage> {\r\n        return this.invoke(PowerShellNotification.subscribe, id);\r\n    }\r\n\r\n    /**\r\n     * The client handler to process message.\r\n     *\r\n     * @param notification the message notification.\r\n     */\r\n    protected clientHandler(notification: SocketMessage<PowerShellWorkItemMessage | NotificationMessage>): void {\r\n        this.subjectInternal.next(notification);\r\n    }\r\n\r\n    /**\r\n     * Process the message.\r\n     *\r\n     * @param messages the messages.\r\n     */\r\n    protected processMessage(message: string): void {\r\n        if (!message) {\r\n            const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.NotificationEmptyMessage.message;\r\n            Logging.log({ source: 'socket', level: LogLevel.Warning, message: message2 });\r\n            return;\r\n        }\r\n\r\n        const data: any = JSON.parse(message);\r\n        if (data.sessionId) {\r\n            // PowerShell work item.\r\n            this.processPowerShellData(data);\r\n            return;\r\n        }\r\n\r\n        if (data.id) {\r\n            // Notification message.\r\n            this.processMessageData(data);\r\n            return;\r\n        }\r\n    }\r\n\r\n    private processPowerShellData(data: PowerShellWorkItemMessage): void {\r\n        /* tslint:disable:no-bitwise */\r\n        let type: SocketMessageFlags = SocketMessageFlags.None;\r\n        if (data.results && data.results.length > 0) {\r\n            type |= SocketMessageFlags.Data;\r\n        }\r\n\r\n        if (data.progress && data.progress.length > 0) {\r\n            type |= SocketMessageFlags.Progress;\r\n        }\r\n\r\n        if (data.errors && data.errors.length > 0) {\r\n            type |= SocketMessageFlags.Error;\r\n        }\r\n\r\n        if (data.exception) {\r\n            type |= SocketMessageFlags.Exception;\r\n        }\r\n\r\n        if (data.completed === 'True') {\r\n            type |= SocketMessageFlags.Completed;\r\n        }\r\n\r\n        this.clientHandler({ type: type, message: data });\r\n    }\r\n\r\n    private processMessageData(message: NotificationMessage): void {\r\n        const type: SocketMessageFlags = SocketMessageFlags.Data;\r\n        this.clientHandler({ type, message });\r\n    }\r\n}\r\n"]}