{"version":3,"sources":["../../../packages/core/data/powershell-alternate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAiB,cAAc,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAc,iBAAiB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAE9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;GAEG;AACH,qBAAa,mBAAmB;IAC5B;;OAEG;IACH,gBAAuB,eAAe,YAAY;IAElD;;;;;;;OAOG;WACW,MAAM,CAAC,CAAC,EACd,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,GAAG,UAAU,CAAC,CAAC,CAAC;IAiBnD;;;;;;;OAOG;WACW,YAAY,CAAC,CAAC,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,GAAG,UAAU,CAAC,CAAC,CAAC;IAmBnD;;;;;;;;;;OAUG;WACW,WAAW,CACjB,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,kBAAkB,GAAG,UAAU,CAAC,iBAAiB,EAAE,CAAC;IA+BrE;;;;;;OAMG;WACW,cAAc,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,+BAA+B,GAAG,iBAAiB;IAIpI;;;;OAIG;WACW,cAAc,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAI9D;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,0BAA0B;IASzC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA6BjC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAsD/B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;CA4BlC","file":"powershell-alternate.d.ts","sourcesContent":["import { Observable } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\nimport { AppContext } from './app-context';\r\nimport { BatchConnection, BatchResponseItem } from './batch-connection';\r\nimport { NodeCimOutput, NodeConnection, NodeRequestOptions } from './node-connection';\r\nimport { PowerShell, PowerShellSession, PowerShellSessionRequestOptions } from './powershell';\r\nimport { PowerShellBatch } from './powershell-batch';\r\nimport { PowerShellStream } from './powershell-stream';\r\n\r\n/**\r\n * The PowerShell Alternate processing class.\r\n */\r\nexport class PowerShellAlternate {\r\n    /**\r\n     * The key of powershell session.\r\n     */\r\n    public static readonly cimAlternateKey = 'cimAlt';\r\n\r\n    /**\r\n     * Create alternate PowerShell query for CIM query.\r\n     *\r\n     * @param nodeConnection The node connection object.\r\n     * @param nodeName The node name.\r\n     * @param options The node request options.\r\n     * @return Observable<T> if there is no alternate available, return null.\r\n     */\r\n    public static create<T>(\r\n            nodeConnection: NodeConnection,\r\n            nodeName: string,\r\n            options: NodeRequestOptions): Observable<T> {\r\n\r\n        if (options == null || options.powerShell == null || options.powerShellContext == null) {\r\n            return null;\r\n        }\r\n\r\n        const endpoint = nodeConnection.getJeaEndpoint(nodeName);\r\n        if (endpoint == null && options.powerShellEndpoint == null && !MsftSme.self().Init.powerShellEndpoint) {\r\n            return null;\r\n        }\r\n\r\n        const powerShell = PowerShellAlternate.findOrCreateNullPowerShell(nodeName, nodeConnection, options);\r\n        const command = PowerShell.createCommand(options.powerShell, options.powerShellContext.parameters);\r\n        return powerShell.run(command)\r\n            .pipe(map(results => PowerShellAlternate.mapPowerShellToCim(options.powerShellContext.cimOutput, results)));\r\n    }\r\n\r\n    /**\r\n     * Create alternate PowerShell Stream query for CIM query.\r\n     *\r\n     * @param nodeConnection The node connection object.\r\n     * @param nodeName The node name.\r\n     * @param options The node request options.\r\n     * @return Observable<T> if there is no alternate available, return null.\r\n     */\r\n    public static createStream<T>(\r\n            powerShellStream: PowerShellStream,\r\n            nodeName: string,\r\n            options: NodeRequestOptions): Observable<T> {\r\n        if (options == null || options.powerShell == null || options.powerShellContext == null) {\r\n            return null;\r\n        }\r\n\r\n        const endpoint = powerShellStream.getJeaEndpoint(nodeName);\r\n        if (endpoint == null && options.powerShellEndpoint == null && !MsftSme.self().Init.powerShellEndpoint) {\r\n            return null;\r\n        }\r\n\r\n        if (!options.powerShellEndpoint) {\r\n            options.powerShellEndpoint = endpoint;\r\n        }\r\n\r\n        const command = PowerShell.createCommand(options.powerShell, options.powerShellContext.parameters);\r\n        return powerShellStream.run(nodeName, command, options)\r\n            .pipe(map(results => PowerShellAlternate.mapPowerShellToCim(options.powerShellContext.cimOutput, results)));\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * (not supported)\r\n     * Create alternate PowerShell Batch query for CIM batch query.\r\n     *\r\n     * @param nodeConnection the node connection object\r\n     * @param batchConnection The batch connection object.\r\n     * @param nodeNames The list of node names.\r\n     * @param options The node request options.\r\n     * @return Observable<BatchResponseItem[]> if there is no alternate available, return null.\r\n     */\r\n    public static createBatch(\r\n            nodeConnection: NodeConnection,\r\n            batchConnection: BatchConnection,\r\n            nodeNames: string[],\r\n            options: NodeRequestOptions): Observable<BatchResponseItem[]> {\r\n        if (options == null || options.powerShell == null || options.powerShellContext == null) {\r\n            return null;\r\n        }\r\n\r\n        // TODO: for now we assume all endpoints match. Need to work on a more general solution.\r\n        const node = nodeNames && nodeNames.length > 0 && nodeNames[0];\r\n        const endpoint = nodeConnection.getJeaEndpoint(node);\r\n        if (endpoint == null && options.powerShellEndpoint == null && !MsftSme.self().Init.powerShellEndpoint) {\r\n            return null;\r\n        }\r\n\r\n        if (!options.powerShellEndpoint) {\r\n            options.powerShellEndpoint = endpoint;\r\n        }\r\n\r\n        const batchSession = new PowerShellBatch(nodeNames, batchConnection, null, null, options);\r\n        const command = PowerShell.createCommand(options.powerShell, options.powerShellContext.parameters);\r\n        return batchSession.runSingleCommand(command, options)\r\n            .pipe(\r\n                map(items => items.map(item =>\r\n                    <BatchResponseItem>{\r\n                        sequenceNumber: item.sequenceNumber,\r\n                        nodeName: item.nodeName,\r\n                        response: {\r\n                            response: PowerShellAlternate.mapPowerShellToCim(options.powerShellContext.cimOutput, item.properties),\r\n                            status: item.status\r\n                        }\r\n                    })));\r\n    }\r\n\r\n    /**\r\n     * Reserve a session for all alternate CIM non-batch query.\r\n     *\r\n     * @param nodeName the node name.\r\n     * @param nodeConnection the node connection object.\r\n     * @param options the node request options.\r\n     */\r\n    public static reserveSession(appContext: AppContext, nodeName: string, options?: PowerShellSessionRequestOptions): PowerShellSession {\r\n        return appContext.powerShell.createSession(nodeName, PowerShellAlternate.cimAlternateKey, options);\r\n    }\r\n\r\n    /**\r\n     * Dispose the session for alternate CIM non-batch query.\r\n     *\r\n     * @param session the session object.\r\n     */\r\n    public static disposeSession(session: PowerShellSession): void {\r\n        session.dispose();\r\n    }\r\n\r\n    /**\r\n     * Find existing powershell session with the fixed key or create null session.\r\n     *\r\n     * @param nodeName the node name.\r\n     * @param nodeConnection the node connection object.\r\n     * @param options the node request options.\r\n     */\r\n    private static findOrCreateNullPowerShell(nodeName: string, nodeConnection: NodeConnection, options: NodeRequestOptions): PowerShell {\r\n        let powerShell = PowerShell.find(nodeName, PowerShellAlternate.cimAlternateKey);\r\n        if (powerShell == null) {\r\n            powerShell = PowerShell.create(nodeName, nodeConnection, null, null, options);\r\n        }\r\n\r\n        return powerShell;\r\n    }\r\n\r\n    /**\r\n     * Convert the PowerShell results to Cim expected format.\r\n     *\r\n     * @param outputType The output data type.\r\n     * @param data The input data.\r\n     */\r\n    private static mapPowerShellToCim(outputType: NodeCimOutput, data: any): any {\r\n        switch (outputType) {\r\n            case NodeCimOutput.Single:\r\n                // single instance result.\r\n                return {\r\n                    properties: data.results && data.results[0] && PowerShellAlternate.cleanCimInstance(data.results[0])\r\n                };\r\n            case NodeCimOutput.Multiple:\r\n                // multiple instances result.\r\n                return {\r\n                    value: data.results.map(instance => {\r\n                        return {\r\n                            properties: PowerShellAlternate.cleanCimInstance(instance)\r\n                        };\r\n                    })\r\n                };\r\n            case NodeCimOutput.Result:\r\n                return PowerShellAlternate.adjustCimResults(data);\r\n\r\n            case NodeCimOutput.Query:\r\n                // query results without properties.\r\n                return {\r\n                    value: data.results.map(instance => {\r\n                        return PowerShellAlternate.cleanCimInstance(instance);\r\n                    })\r\n                };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adjust PowerShell CIM results data.\r\n     *\r\n     * @param data The result data.\r\n     */\r\n    private static adjustCimResults(data: any): any {\r\n        let response: any = {};\r\n\r\n        // invoke method results with free structured but index 0.\r\n        if (!data.results) {\r\n            return response;\r\n        }\r\n\r\n        if (data.results.length === 0) {\r\n            return response;\r\n        }\r\n\r\n        //\r\n        // Packed the same parameterName object into single array.\r\n        //\r\n        // parameterName\r\n        // itemType: 16: Instance\r\n        // itemValue: Instance Data\r\n        // psComputerName\r\n        //\r\n        const results: any = [];\r\n        for (const item of data.results) {\r\n            if (item['psComputerName'] !== undefined) {\r\n                delete item['psComputerName'];\r\n            }\r\n\r\n            if (item.hasOwnProperty('returnValue')) {\r\n                response = { ...response, ...item };\r\n            }\r\n\r\n            if (item.hasOwnProperty('outParameters')) {\r\n                for (const parameter of item.outParameters) {\r\n                    response[parameter.name] = parameter.value;\r\n                }\r\n            }\r\n\r\n            // aggregate the same parameter name object into single array.\r\n            if (item.hasOwnProperty('itemValue')) {\r\n                if (item.itemValue.length > 0) {\r\n                    const array: any[] = item.itemValue;\r\n                    array.forEach(value => results.push(PowerShellAlternate.cleanCimInstance(value)));\r\n                } else {\r\n                    results.push(PowerShellAlternate.cleanCimInstance(item.itemValue));\r\n                }\r\n            }\r\n        }\r\n\r\n        if (results.length > 0) {\r\n            response.results = results;\r\n        }\r\n\r\n        return response;\r\n    }\r\n\r\n    /**\r\n     * Clean the cim instance object to remove schema/qualifier data.\r\n     *\r\n     * @param data The instance object from PowerShell.\r\n     */\r\n    private static cleanCimInstance(data: any): any {\r\n        if (!data) {\r\n            return data;\r\n        }\r\n\r\n        if (data['psComputerName'] !== undefined) {\r\n            delete data['psComputerName'];\r\n        }\r\n\r\n        if (data['cimClass']) {\r\n            delete data['cimClass'];\r\n        }\r\n\r\n        if (data['cimInstanceProperties']) {\r\n            delete data['cimInstanceProperties'];\r\n        }\r\n\r\n        if (data['cimSystemProperties']) {\r\n            const props = data['cimSystemProperties'];\r\n            data['_Namespace'] = props['namespace'];\r\n            data['_ServerName'] = props['serverName'];\r\n            data['_ClassName'] = props['className'];\r\n            data['_Path'] = props['path'];\r\n            delete data['cimSystemProperties'];\r\n        }\r\n\r\n        return data;\r\n    }\r\n}\r\n"]}