all files / DEV/lib/utils/ RequestHandler.js

91.75% Statements 89/97
72.15% Branches 57/79
100% Functions 12/12
66.67% Lines 16/24
10 statements, 15 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
'use strict';
 
Object.defineProperty(exports, '__esModule', {
    value: true
});
// istanbul ignore next
 
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
 
// istanbul ignore next
 
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
E
// istanbul ignore next

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 
var _url = require('url');
 
var _url2 = _interopRequireDefault(_url);
 
var _request = require('request');
 
var _request2 = _interopRequireDefault(_request);
 
var _deepmerge = require('deepmerge');
 
var _deepmerge2 = _interopRequireDefault(_deepmerge);
 
var _helpersConstants = require('../helpers/constants');
 
var _ErrorHandler = require('./ErrorHandler');

var _packageJson = require('../../package.json');
 
var _packageJson2 = _interopRequireDefault(_packageJson);
 
/**
 * RequestHandler
 */
 
var RequestHandler = (function () {
    function RequestHandler(options, eventHandler, logger) {
        _classCallCheck(this, RequestHandler);
 
        this.sessionID = null;
        this.startPath = options.path === '/' ? '' : options.path || '/wd/hub';
        this.eventHandler = eventHandler;I
        this.logger = logger;
        this.defaultOptions = options;
 
        /**
         * actually host is `hostname:port` but to keep config properties
         * short we abuse host as hostname
         */
        if (options.host !== undefined) {
            options.hostname = options.host;
            delete options.host;
        }
 
        /**
         * set auth from user and password configs
         */
        if (this.defaultOptions.user && this.defaultOptions.key) {
            this.auth = {
                user: this.defaultOptions.user,
                pass: this.defaultOptions.key
            };

            delete this.defaultOptions.user;
            delete this.defaultOptions.key;
        }
    }
 
    /**
     * merges default options with request options
     *
     * @param  {Object} requestOptions  request options
     */
 
    _createClass(RequestHandler, [{
        key: 'createOptions',
        value: function createOptions(requestOptions, data) {
            var newOptions = {};
 
            /**
             * if we don't have a session id we set it here, unless we call commands that don't require session ids, for
             * example /sessions. The call to /sessions is not connected to a session itself and it therefore doesn't
             * require it
             */
            if (requestOptions.path.match(/\:sessionId/) && !this.sessionID && requestOptions.requiresSession !== false) {
                // throw session id error
                throw new _ErrorHandler.RuntimeError(101);
            }
 
            newOptions.uri = _url2['default'].parse(this.defaultOptions.protocol + '://' + this.defaultOptions.hostname + ':' + this.defaultOptions.port + this.startPath + requestOptions.path.replace(':sessionId', this.sessionID || ''));
 
            // send authentication credentials only when creating new session
            if (requestOptions.path === '/session' && this.auth !== undefined) {
                newOptions.auth = this.auth;
            }
 
            if (requestOptions.method) {
                newOptions.method = requestOptions.method;
            }
 
            newOptions.json = true;
            newOptions.followAllRedirects = true;
 
            newOptions.headers = {
                'Connection': 'keep-alive',
                'Accept': 'application/json',
                'User-Agent': 'webdriverio/webdriverio/' + _packageJson2['default'].version
            };
 
            if (Object.keys(data).length > 0) {
                var requestData = JSON.stringify(data);
                newOptions.body = requestData;
                newOptions.method = 'POST';
                newOptions.headers = (0, _deepmerge2['default'])(newOptions.headers, {
                    'Content-Type': 'application/json; charset=UTF-8',
                    'Content-Length': Buffer.byteLength(requestData, 'UTF-8')
                });
            }
 
            return newOptions;
        }
 
        /**
         * creates a http request with its given options and send the protocol
         * command to the webdriver server
         *
         * @param  {Object}   requestOptions  defines url, method and other request options
         * @param  {Object}   data            contains request data
         */
    }, {
        key: 'create',
        value: function create(requestOptions, data) {
            // istanbul ignore next
 
            var _this = this;

            data = data || {};
 
            /**
             * allow to pass a string as shorthand argument
             */
            if (typeof requestOptions === 'string') {
                requestOptions = {
                    path: requestOptions
                };
            }
 
            var fullRequestOptions = this.createOptions(requestOptions, data);
 
            this.eventHandler.emit('command', {
                method: fullRequestOptions.method || 'GET',
                uri: fullRequestOptions.uri,
                data: data
            });
 
            return new Promise(function (resolve, reject) {
                (0, _request2['default'])(fullRequestOptions, _this.responseHandler(resolve, reject, data, requestOptions, fullRequestOptions));
            });
        }
 
        /**
         * response handler
         */
    }, {
        key: 'responseHandler',
        value: function responseHandler(resolve, reject, data, requestOptions, fullRequestOptions) {
            // istanbul ignore next
 
            var _this2 = this;
 
            return function (err, response, body) {
                var error = null;
 
                if (err || body && body.status !== 0) {
                    /**
                     * in Appium you find sometimes more exact error messages in origValue
                     */
                    if (body && body.value && typeof body.value.origValue === 'string' && typeof body.value.message === 'string') {
                        body.value.message += ' ' + body.value.origValue;
                    }
 
                    if (body && typeof body === 'string') {
                        error = new _ErrorHandler.RuntimeError(body);
                    } else if (body) {
                        error = new _ErrorHandler.RuntimeError({
                            status: body.status,
                            type: _helpersConstants.ERROR_CODES[body.status] ? _helpersConstants.ERROR_CODES[body.status].id : 'unknown',
                            message: _helpersConstants.ERROR_CODES[body.status] ? _helpersConstants.ERROR_CODES[body.status].message : 'unknown',
                            orgStatusMessage: body.value ? body.value.message : '',
                            screenshot: body.value && body.value.screen || null
                        });
                    } else if (err.message.indexOf('Nock') > -1) {
                        // for better unit test error output
                        error = err;
                    } else {
                        error = new _ErrorHandler.RuntimeError({
                            status: -1,
                            type: 'ECONNREFUSED',
                            message: 'Couldn\'t connect to selenium server',
                            orgStatusMessage: 'Couldn\'t connect to selenium server'
                        });
                    }
 
                    return reject(error);
                }
 
                /**
                 * if no session id was set before we've called the init command
                 */
                if (_this2.sessionID === null && requestOptions.requiresSession !== false) {
                    _this2.sessionID = body.sessionId;
 
                    _this2.eventHandler.emit('init', {
                        sessionID: _this2.sessionID,
                        options: body.value,
                        desiredCapabilities: data.desiredCapabilities
                    });
 
                    _this2.logger.log('SET SESSION ID ' + _this2.sessionID);
                }
 
                if (body === undefined) {
                    body = {
                        status: 0,
                        orgStatusMessage: _helpersConstants.ERROR_CODES[0].message
                    };
                }
 
                _this2.eventHandler.emit('result', {
                    requestData: data,
                    requestOptions: fullRequestOptions,
                    response: response,
                    body: body
                });
 
                return resolve(body);
            };
        }
    }]);
 
    return RequestHandler;
})();
 
exports['default'] = RequestHandler;
module.exports = exports['default'];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9jaHJpc3RpYW5icm9tYW5uL1NpdGVzL1dlYnByb2pla3RlL3dlYmRyaXZlcmpzL0RFVi9saWIvdXRpbHMvUmVxdWVzdEhhbmRsZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7bUJBQWdCLEtBQUs7Ozs7dUJBQ0QsU0FBUzs7Ozt5QkFDWCxXQUFXOzs7O2dDQUVELHNCQUFzQjs7NEJBQ3JCLGdCQUFnQjs7MkJBQzdCLG9CQUFvQjs7Ozs7Ozs7SUFLOUIsY0FBYztBQUNKLGFBRFYsY0FBYyxDQUNILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFOzhCQUQxQyxjQUFjOztBQUVaLFlBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFBO0FBQ3JCLFlBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLElBQUksS0FBSyxHQUFHLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFBO0FBQ3RFLFlBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFBO0FBQ2hDLFlBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO0FBQ3BCLFlBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFBOzs7Ozs7QUFNN0IsWUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTtBQUM1QixtQkFBTyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFBO0FBQy9CLG1CQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUE7U0FDdEI7Ozs7O0FBS0QsWUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRTtBQUNyRCxnQkFBSSxDQUFDLElBQUksR0FBRztBQUNSLG9CQUFJLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJO0FBQzlCLG9CQUFJLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHO2FBQ2hDLENBQUE7O0FBRUQsbUJBQU8sSUFB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QUFHO0FBQ0gsOEJBQU0sRUFBRSxDQUFDO0FBQ1Qsd0NBQWdCLEVBQUUsOEJBQVksQ0FBQyxDQUFDLENBQUMsT0FBTztxQkFDM0MsQ0FBQTtpQkFDSjs7QUFFRCx1QkFBSyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtBQUM3QiwrQkFBVyxFQUFFLElBQUk7QUFDakIsa0NBQWMsRUFBRSxrQkFBa0I7QUFDbEMsNEJBQVEsRUFBRSxRQUFRO0FBQ2xCLHdCQUFJLEVBQUUsSUFBSTtpQkFDYixDQUFDLENBQUE7O0FBRUYsdUJBQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO2FBQ3ZCLENBQUE7U0FDSjs7O1dBN0xDLGNBQWM7OztxQkFnTUwsY0FBYyIsImZpbGUiOiIvVXNlcnMvY2hyaXN0aWFuYnJvbWFubi9TaXRlcy9XZWJwcm9qZWt0ZS93ZWJkcml2ZXJqcy9ERVYvbGliL3V0aWxzL1JlcXVlc3RIYW5kbGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHVybCBmcm9tICd1cmwnXG5pbXBvcnQgcmVxdWVzdCBmcm9tICdyZXF1ZXN0J1xuaW1wb3J0IG1lcmdlIGZyb20gJ2RlZXBtZXJnZSdcblxuaW1wb3J0IHsgRVJST1JfQ09ERVMgfSBmcm9tICcuLi9oZWxwZXJzL2NvbnN0YW50cydcbmltcG9ydCB7IFJ1bnRpbWVFcnJvciB9IGZyb20gJy4vRXJyb3JIYW5kbGVyJ1xuaW1wb3J0IHBrZyBmcm9tICcuLi8uLi9wYWNrYWdlLmpzb24nXG5cbi8qKlxuICogUmVxdWVzdEhhbmRsZXJcbiAqL1xuY2xhc3MgUmVxdWVzdEhhbmRsZXIge1xuICAgIGNvbnN0cnVjdG9yIChvcHRpb25zLCBldmVudEhhbmRsZXIsIGxvZ2dlcikge1xuICAgICAgICB0aGlzLnNlc3Npb25JRCA9IG51bGxcbiAgICAgICAgdGhpcy5zdGFydFBhdGggPSBvcHRpb25zLnBhdGggPT09ICcvJyA/ICcnIDogb3B0aW9ucy5wYXRoIHx8ICcvd2QvaHViJ1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlciA9IGV2ZW50SGFuZGxlclxuICAgICAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlclxuICAgICAgICB0aGlzLmRlZmF1bHRPcHRpb25zID0gb3B0aW9uc1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhY3R1YWxseSBob3N0IGlzIGBob3N0bmFtZTpwb3J0YCBidXQgdG8ga2VlcCBjb25maWcgcHJvcGVydGllc1xuICAgICAgICAgKiBzaG9ydCB3ZSBhYnVzZSBob3N0IGFzIGhvc3RuYW1lXG4gICAgICAgICAqL1xuICAgICAgICBpZiAob3B0aW9ucy5ob3N0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuaG9zdG5hbWUgPSBvcHRpb25zLmhvc3RcbiAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zLmhvc3RcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBzZXQgYXV0aCBmcm9tIHVzZXIgYW5kIHBhc3N3b3JkIGNvbmZpZ3NcbiAgICAgICAgICovXG4gICAgICAgIGlmICh0aGlzLmRlZmF1bHRPcHRpb25zLnVzZXIgJiYgdGhpcy5kZWZhdWx0T3B0aW9ucy5rZXkpIHtcbiAgICAgICAgICAgIHRoaXMuYXV0aCA9IHtcbiAgICAgICAgICAgICAgICB1c2VyOiB0aGlzLmRlZmF1bHRPcHRpb25zLnVzZXIsXG4gICAgICAgICAgICAgICAgcGFzczogdGhpcy5kZWZhdWx0T3B0aW9ucy5rZXlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuZGVmYXVsdE9wdGlvbnMudXNlclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuZGVmYXVsdE9wdGlvbnMua2V5XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBtZXJnZXMgZGVmYXVsdCBvcHRpb25zIHdpdGggcmVxdWVzdCBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zICByZXF1ZXN0IG9wdGlvbnNcbiAgICAgKi9cbiAgICBjcmVhdGVPcHRpb25zIChyZXF1ZXN0T3B0aW9ucywgZGF0YSkge1xuICAgICAgICBsZXQgbmV3T3B0aW9ucyA9IHt9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGlmIHdlIGRvbid0IGhhdmUgYSBzZXNzaW9uIGlkIHdlIHNldCBpdCBoZXJlLCB1bmxlc3Mgd2UgY2FsbCBjb21tYW5kcyB0aGF0IGRvbid0IHJlcXVpcmUgc2Vzc2lvbiBpZHMsIGZvclxuICAgICAgICAgKiBleGFtcGxlIC9zZXNzaW9ucy4gVGhlIGNhbGwgdG8gL3Nlc3Npb25zIGlzIG5vdCBjb25uZWN0ZWQgdG8gYSBzZXNzaW9uIGl0c2VsZiBhbmQgaXQgdGhlcmVmb3JlIGRvZXNuJ3RcbiAgICAgICAgICogcmVxdWlyZSBpdFxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLnBhdGgubWF0Y2goL1xcOnNlc3Npb25JZC8pICYmICF0aGlzLnNlc3Npb25JRCAmJiByZXF1ZXN0T3B0aW9ucy5yZXF1aXJlc1Nlc3Npb24gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAvLyB0aHJvdyBzZXNzaW9uIGlkIGVycm9yXG4gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDEwMSlcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld09wdGlvbnMudXJpID0gdXJsLnBhcnNlKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0T3B0aW9ucy5wcm90b2NvbCArICc6Ly8nICtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdE9wdGlvbnMuaG9zdG5hbWUgKyAnOicgKyB0aGlzLmRlZmF1bHRPcHRpb25zLnBvcnQgK1xuICAgICAgICAgICAgdGhpcy5zdGFydFBhdGggK1xuICAgICAgICAgICAgcmVxdWVzdE9wdGlvbnMucGF0aC5yZXBsYWNlKCc6c2Vzc2lvbklkJywgdGhpcy5zZXNzaW9uSUQgfHwgJycpKVxuXG4gICAgICAgIC8vIHNlbmQgYXV0aGVudGljYXRpb24gY3JlZGVudGlhbHMgb25seSB3aGVuIGNyZWF0aW5nIG5ldyBzZXNzaW9uXG4gICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5wYXRoID09PSAnL3Nlc3Npb24nICYmIHRoaXMuYXV0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBuZXdPcHRpb25zLmF1dGggPSB0aGlzLmF1dGhcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5tZXRob2QpIHtcbiAgICAgICAgICAgIG5ld09wdGlvbnMubWV0aG9kID0gcmVxdWVzdE9wdGlvbnMubWV0aG9kXG4gICAgICAgIH1cblxuICAgICAgICBuZXdPcHRpb25zLmpzb24gPSB0cnVlXG4gICAgICAgIG5ld09wdGlvbnMuZm9sbG93QWxsUmVkaXJlY3RzID0gdHJ1ZVxuXG4gICAgICAgIG5ld09wdGlvbnMuaGVhZGVycyA9IHtcbiAgICAgICAgICAgICdDb25uZWN0aW9uJzogJ2tlZXAtYWxpdmUnLFxuICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICdVc2VyLUFnZW50JzogJ3dlYmRyaXZlcmlvL3dlYmRyaXZlcmlvLycgKyBwa2cudmVyc2lvblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGRhdGEpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxldCByZXF1ZXN0RGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpXG4gICAgICAgICAgICBuZXdPcHRpb25zLmJvZHkgPSByZXF1ZXN0RGF0YVxuICAgICAgICAgICAgbmV3T3B0aW9ucy5tZXRob2QgPSAnUE9TVCdcbiAgICAgICAgICAgIG5ld09wdGlvbnMuaGVhZGVycyA9IG1lcmdlKG5ld09wdGlvbnMuaGVhZGVycywge1xuICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgICAgICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogQnVmZmVyLmJ5dGVMZW5ndGgocmVxdWVzdERhdGEsICdVVEYtOCcpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ld09wdGlvbnNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBjcmVhdGVzIGEgaHR0cCByZXF1ZXN0IHdpdGggaXRzIGdpdmVuIG9wdGlvbnMgYW5kIHNlbmQgdGhlIHByb3RvY29sXG4gICAgICogY29tbWFuZCB0byB0aGUgd2ViZHJpdmVyIHNlcnZlclxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIHJlcXVlc3RPcHRpb25zICBkZWZpbmVzIHVybCwgbWV0aG9kIGFuZCBvdGhlciByZXF1ZXN0IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgZGF0YSAgICAgICAgICAgIGNvbnRhaW5zIHJlcXVlc3QgZGF0YVxuICAgICAqL1xuICAgIGNyZWF0ZSAocmVxdWVzdE9wdGlvbnMsIGRhdGEpIHtcbiAgICAgICAgZGF0YSA9IGRhdGEgfHwge31cblxuICAgICAgICAvKipcbiAgICAgICAgICogYWxsb3cgdG8gcGFzcyBhIHN0cmluZyBhcyBzaG9ydGhhbmQgYXJndW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIGlmICh0eXBlb2YgcmVxdWVzdE9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBwYXRoOiByZXF1ZXN0T3B0aW9uc1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZ1bGxSZXF1ZXN0T3B0aW9ucyA9IHRoaXMuY3JlYXRlT3B0aW9ucyhyZXF1ZXN0T3B0aW9ucywgZGF0YSlcblxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5lbWl0KCdjb21tYW5kJywge1xuICAgICAgICAgICAgbWV0aG9kOiBmdWxsUmVxdWVzdE9wdGlvbnMubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgICAgICAgdXJpOiBmdWxsUmVxdWVzdE9wdGlvbnMudXJpLFxuICAgICAgICAgICAgZGF0YTogZGF0YVxuICAgICAgICB9KVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICByZXF1ZXN0KGZ1bGxSZXF1ZXN0T3B0aW9ucywgdGhpcy5yZXNwb25zZUhhbmRsZXIocmVzb2x2ZSwgcmVqZWN0LCBkYXRhLCByZXF1ZXN0T3B0aW9ucywgZnVsbFJlcXVlc3RPcHRpb25zKSlcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiByZXNwb25zZSBoYW5kbGVyXG4gICAgICovXG4gICAgcmVzcG9uc2VIYW5kbGVyIChyZXNvbHZlLCByZWplY3QsIGRhdGEsIHJlcXVlc3RPcHRpb25zLCBmdWxsUmVxdWVzdE9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIChlcnIsIHJlc3BvbnNlLCBib2R5KSA9PiB7XG4gICAgICAgICAgICBsZXQgZXJyb3IgPSBudWxsXG5cbiAgICAgICAgICAgIGlmIChlcnIgfHwgKGJvZHkgJiYgYm9keS5zdGF0dXMgIT09IDApKSB7XG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogaW4gQXBwaXVtIHlvdSBmaW5kIHNvbWV0aW1lcyBtb3JlIGV4YWN0IGVycm9yIG1lc3NhZ2VzIGluIG9yaWdWYWx1ZVxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChib2R5ICYmIGJvZHkudmFsdWUgJiYgdHlwZW9mIGJvZHkudmFsdWUub3JpZ1ZhbHVlID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgYm9keS52YWx1ZS5tZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBib2R5LnZhbHVlLm1lc3NhZ2UgKz0gJyAnICsgYm9keS52YWx1ZS5vcmlnVmFsdWVcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoYm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgUnVudGltZUVycm9yKGJvZHkpXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IFJ1bnRpbWVFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IGJvZHkuc3RhdHVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogRVJST1JfQ09ERVNbYm9keS5zdGF0dXNdID8gRVJST1JfQ09ERVNbYm9keS5zdGF0dXNdLmlkIDogJ3Vua25vd24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogRVJST1JfQ09ERVNbYm9keS5zdGF0dXNdID8gRVJST1JfQ09ERVNbYm9keS5zdGF0dXNdLm1lc3NhZ2UgOiAndW5rbm93bicsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmdTdGF0dXNNZXNzYWdlOiBib2R5LnZhbHVlID8gYm9keS52YWx1ZS5tZXNzYWdlIDogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5zaG90OiBib2R5LnZhbHVlICYmIGJvZHkudmFsdWUuc2NyZWVuIHx8IG51bGxcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVyci5tZXNzYWdlLmluZGV4T2YoJ05vY2snKSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGZvciBiZXR0ZXIgdW5pdCB0ZXN0IGVycm9yIG91dHB1dFxuICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGVyclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IFJ1bnRpbWVFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IC0xLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0VDT05OUkVGVVNFRCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnQ291bGRuXFwndCBjb25uZWN0IHRvIHNlbGVuaXVtIHNlcnZlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmdTdGF0dXNNZXNzYWdlOiAnQ291bGRuXFwndCBjb25uZWN0IHRvIHNlbGVuaXVtIHNlcnZlcidcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIGlmIG5vIHNlc3Npb24gaWQgd2FzIHNldCBiZWZvcmUgd2UndmUgY2FsbGVkIHRoZSBpbml0IGNvbW1hbmRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbklEID09PSBudWxsICYmIHJlcXVlc3RPcHRpb25zLnJlcXVpcmVzU2Vzc2lvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25JRCA9IGJvZHkuc2Vzc2lvbklkXG5cbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5lbWl0KCdpbml0Jywge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSUQ6IHRoaXMuc2Vzc2lvbklELFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBib2R5LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBkZXNpcmVkQ2FwYWJpbGl0aWVzOiBkYXRhLmRlc2lyZWRDYXBhYmlsaXRpZXNcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKCdTRVQgU0VTU0lPTiBJRCAnICsgdGhpcy5zZXNzaW9uSUQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChib2R5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IDAsXG4gICAgICAgICAgICAgICAgICAgIG9yZ1N0YXR1c01lc3NhZ2U6IEVSUk9SX0NPREVTWzBdLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZXZlbnRIYW5kbGVyLmVtaXQoJ3Jlc3VsdCcsIHtcbiAgICAgICAgICAgICAgICByZXF1ZXN0RGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICByZXF1ZXN0T3B0aW9uczogZnVsbFJlcXVlc3RPcHRpb25zLFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlOiByZXNwb25zZSxcbiAgICAgICAgICAgICAgICBib2R5OiBib2R5XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShib2R5KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0SGFuZGxlclxuIl19