UNPKG

@cloudbase/app

Version:
480 lines 62.9 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getRequestByEnvId = exports.initRequest = exports.CloudbaseRequest = void 0; var common_1 = require("../constants/common"); var utilities_1 = require("@cloudbase/utilities"); var cache_1 = require("./cache"); var adapter_1 = require("./adapter"); var ERRORS = utilities_1.constants.ERRORS; var genSeqId = utilities_1.utils.genSeqId, isFormData = utilities_1.utils.isFormData, formatUrl = utilities_1.utils.formatUrl; var ACTIONS_WITHOUT_ACCESSTOKEN = [ 'auth.getJwt', 'auth.logout', 'auth.signInWithTicket', 'auth.signInAnonymously', 'auth.signIn', 'auth.fetchAccessTokenWithRefreshToken', 'auth.signUpWithEmailAndPassword', 'auth.activateEndUserMail', 'auth.sendPasswordResetEmail', 'auth.resetPasswordWithToken', 'auth.isUsernameRegistered', ]; function bindHooks(instance, name, hooks) { var originMethod = instance[name]; instance[name] = function (options) { var data = {}; var headers = {}; hooks.forEach(function (hook) { var _a = hook.call(instance, options), appendedData = _a.data, appendedHeaders = _a.headers; Object.assign(data, appendedData); Object.assign(headers, appendedHeaders); }); var originData = options.data; originData && (function () { if (isFormData(originData)) { Object.keys(data).forEach(function (key) { originData.append(key, data[key]); }); return; } options.data = __assign(__assign({}, originData), data); })(); options.headers = __assign(__assign({}, (options.headers || {})), headers); return originMethod.call(instance, options); }; } function beforeEach() { var seqId = genSeqId(); return { data: { seqId: seqId, }, headers: { 'X-SDK-Version': "@cloudbase/js-sdk/".concat((0, common_1.getSdkVersion)()), 'x-seqid': seqId, }, }; } var CloudbaseRequest = (function () { function CloudbaseRequest(config) { var _this = this; this.throwWhenRequestFail = false; this.config = config; var reqConfig = { timeout: this.config.timeout, timeoutMsg: "[@cloudbase/js-sdk] \u8BF7\u6C42\u5728".concat(this.config.timeout / 1000, "s\u5185\u672A\u5B8C\u6210\uFF0C\u5DF2\u4E2D\u65AD"), restrictedMethods: ['post', 'put'], auth: config.auth, }; this.reqClass = new adapter_1.Platform.adapter.reqClass(reqConfig); this.throwWhenRequestFail = config.throw || false; this.localCache = (0, cache_1.getLocalCache)(this.config.env); if (this.config.endPointMode !== 'GATEWAY') { bindHooks(this.reqClass, 'post', [beforeEach]); bindHooks(this.reqClass, 'upload', [beforeEach]); bindHooks(this.reqClass, 'download', [beforeEach]); } utilities_1.langEvent.bus.on(utilities_1.langEvent.LANG_CHANGE_EVENT, function (params) { var _a; _this.config.i18n = ((_a = params.data) === null || _a === void 0 ? void 0 : _a.i18n) || _this.config.i18n; }); } CloudbaseRequest.prototype.getAccessToken = function (token) { if (token === void 0) { token = null; } return __awaiter(this, void 0, void 0, function () { var app, oauthInstance, oauthClient; return __generator(this, function (_a) { switch (_a.label) { case 0: if (token != null) { return [2, token]; } app = this.config._fromApp; if (!app.oauthInstance) { throw new Error('you can\'t request without auth'); } oauthInstance = app.oauthInstance; oauthClient = oauthInstance.oauth2client; return [4, this.getOauthAccessTokenV2(oauthClient)]; case 1: return [2, (_a.sent()).accessToken]; } }); }); }; CloudbaseRequest.prototype.getDefaultHeaders = function () { var _a; var _b, _c; return _a = {}, _a[(_b = this.config.i18n) === null || _b === void 0 ? void 0 : _b.LANG_HEADER_KEY] = (_c = this.config.i18n) === null || _c === void 0 ? void 0 : _c.lang, _a['X-SDK-Version'] = "@cloudbase/js-sdk/".concat((0, common_1.getSdkVersion)()), _a; }; CloudbaseRequest.prototype.post = function (options, customReqOpts) { return __awaiter(this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.reqClass.post(__assign(__assign({}, options), { headers: __assign(__assign({}, options.headers), this.getDefaultHeaders()), customReqOpts: customReqOpts }))]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.upload = function (options) { return __awaiter(this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.reqClass.upload(__assign(__assign({}, options), { headers: __assign(__assign({}, options.headers), this.getDefaultHeaders()) }))]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.download = function (options) { return __awaiter(this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.reqClass.download(__assign(__assign({}, options), { headers: __assign(__assign({}, options.headers), this.getDefaultHeaders()) }))]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.getBaseEndPoint = function (endPointKey) { if (endPointKey === void 0) { endPointKey = 'CLOUD_API'; } return (0, common_1.getBaseEndPoint)(this.config.env, endPointKey); }; CloudbaseRequest.prototype.getOauthAccessTokenV2 = function (oauthClient) { return __awaiter(this, void 0, void 0, function () { var validAccessToken, credentials; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, oauthClient.getAccessToken()]; case 1: validAccessToken = _a.sent(); return [4, oauthClient.getCredentials()]; case 2: credentials = _a.sent(); return [2, { accessToken: validAccessToken, accessTokenExpire: new Date(credentials.expires_at).getTime(), }]; } }); }); }; CloudbaseRequest.prototype.request = function (action, params, options, customReqOpts) { var _a, _b; return __awaiter(this, void 0, void 0, function () { var tcbTraceKey, contentType, tmpObj_1, app, oauthInstance, oauthClient, _c, payload_1, opts, traceHeader, parse, inQuery, search, formatQuery, endPointMode, url, BASE_URL, PROTOCOL, url_1, newUrl, res, resTraceHeader, err_1; return __generator(this, function (_d) { switch (_d.label) { case 0: _d.trys.push([0, 4, , 5]); tcbTraceKey = "x-tcb-trace_".concat(this.config.env); contentType = 'application/x-www-form-urlencoded'; tmpObj_1 = __assign({ action: action, dataVersion: common_1.DATA_VERSION, env: this.config.env }, params); if (!(ACTIONS_WITHOUT_ACCESSTOKEN.indexOf(action) === -1)) return [3, 2]; app = this.config._fromApp; if (!app.oauthInstance) { throw new Error('you can\'t request without auth'); } oauthInstance = app.oauthInstance; oauthClient = oauthInstance.oauth2client; _c = tmpObj_1; return [4, this.getOauthAccessTokenV2(oauthClient)]; case 1: _c.access_token = (_d.sent()).accessToken; _d.label = 2; case 2: if (action === 'storage.uploadFile') { payload_1 = new FormData(); Object.keys(payload_1).forEach(function (key) { if (Object.prototype.hasOwnProperty.call(payload_1, key) && payload_1[key] !== undefined) { payload_1.append(key, tmpObj_1[key]); } }); contentType = 'multipart/form-data'; } else { contentType = 'application/json;charset=UTF-8'; payload_1 = {}; Object.keys(tmpObj_1).forEach(function (key) { if (tmpObj_1[key] !== undefined) { payload_1[key] = tmpObj_1[key]; } }); } opts = { headers: __assign(__assign({ 'content-type': contentType }, this.getDefaultHeaders()), options === null || options === void 0 ? void 0 : options.headers), }; if (options === null || options === void 0 ? void 0 : options.onUploadProgress) { opts.onUploadProgress = options.onUploadProgress; } if (this.config.region) { opts.headers['X-TCB-Region'] = this.config.region; } traceHeader = this.localCache.getStore(tcbTraceKey); if (traceHeader) { opts.headers['X-TCB-Trace'] = traceHeader; } parse = (options === null || options === void 0 ? void 0 : options.parse) !== undefined ? options.parse : params.parse; inQuery = (options === null || options === void 0 ? void 0 : options.inQuery) !== undefined ? options.inQuery : params.inQuery; search = (options === null || options === void 0 ? void 0 : options.search) !== undefined ? options.search : params.search; formatQuery = __assign(__assign({}, ((options === null || options === void 0 ? void 0 : options.defaultQuery) || {})), { env: this.config.env }); parse && (formatQuery.parse = true); inQuery && (formatQuery = __assign(__assign({}, inQuery), formatQuery)); endPointMode = (options === null || options === void 0 ? void 0 : options.endPointMode) || this.config.endPointMode || 'CLOUD_API'; url = (0, common_1.getEndPointInfo)(this.config.env, endPointMode); BASE_URL = url.baseUrl; PROTOCOL = url.protocol; if (endPointMode === 'GATEWAY') { if (/^((database)\.)|(auth\.wsWebSign)/.test(action)) { url_1 = (0, common_1.getEndPointInfo)(this.config.env, 'CLOUD_API'); BASE_URL = "".concat(url_1.baseUrl.match(/\/\/([^/?#]*)/)[0], "/web"); } } newUrl = void 0; if (options.pathname) { newUrl = formatUrl(PROTOCOL, "".concat((_a = (0, common_1.getBaseEndPoint)(this.config.env, endPointMode)) === null || _a === void 0 ? void 0 : _a.replace(/^https?:/, ''), "/").concat(options.pathname), formatQuery); } else { newUrl = formatUrl(PROTOCOL, BASE_URL, formatQuery); } if (search) { newUrl += search; } return [4, this.post(__assign({ url: newUrl, data: payload_1 }, opts), customReqOpts)]; case 3: res = _d.sent(); resTraceHeader = (_b = res.header) === null || _b === void 0 ? void 0 : _b['x-tcb-trace']; if (resTraceHeader) { this.localCache.setStore(tcbTraceKey, resTraceHeader); } if ((Number(res.status) !== 200 && Number(res.statusCode) !== 200) || !res.data) { throw new Error('network request error'); } return [2, res]; case 4: err_1 = _d.sent(); try { err_1.requestId = err_1.requestId || (options === null || options === void 0 ? void 0 : options.headers['x-request-id']) || (options === null || options === void 0 ? void 0 : options.headers['X-Request-Id']) || ''; } catch (error) { } throw err_1; case 5: return [2]; } }); }); }; CloudbaseRequest.prototype.fetch = function (options) { var _a, _b, _c, _d, _e, _f, _g, _h; return __awaiter(this, void 0, void 0, function () { var token, _j, headers, _k, withCredentials, restOptions, doFetch, result, err_2; var _this = this; return __generator(this, function (_l) { switch (_l.label) { case 0: token = options.token, _j = options.headers, headers = _j === void 0 ? {} : _j, _k = options.withCredentials, withCredentials = _k === void 0 ? true : _k, restOptions = __rest(options, ["token", "headers", "withCredentials"]); doFetch = function () { return __awaiter(_this, void 0, void 0, function () { var authHeaders, _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: authHeaders = {}; if (!withCredentials) return [3, 2]; _a = authHeaders; _b = "Bearer ".concat; return [4, this.getAccessToken(token)]; case 1: _a.Authorization = _b.apply("Bearer ", [_c.sent()]); _c.label = 2; case 2: return [2, this.reqClass.fetch(__assign({ headers: __assign(__assign(__assign({ 'X-SDK-Version': "@cloudbase/js-sdk/".concat((0, common_1.getSdkVersion)()) }, authHeaders), this.getDefaultHeaders()), headers) }, restOptions))]; } }); }); }; _l.label = 1; case 1: _l.trys.push([1, 3, , 6]); return [4, doFetch()]; case 2: result = _l.sent(); return [2, result]; case 3: err_2 = _l.sent(); try { err_2.requestId = err_2.requestId || headers['x-request-id'] || headers['X-Request-Id'] || ''; } catch (error) { } if (!((err_2 === null || err_2 === void 0 ? void 0 : err_2.code) === 'ACCESS_TOKEN_EXPIRED')) return [3, 5]; if (typeof ((_d = (_c = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a._fromApp) === null || _b === void 0 ? void 0 : _b.oauthInstance) === null || _c === void 0 ? void 0 : _c.authApi) === null || _d === void 0 ? void 0 : _d.refreshTokenForce) !== 'function') { throw err_2; } return [4, ((_h = (_g = (_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e._fromApp) === null || _f === void 0 ? void 0 : _f.oauthInstance) === null || _g === void 0 ? void 0 : _g.authApi) === null || _h === void 0 ? void 0 : _h.refreshTokenForce())]; case 4: _l.sent(); return [2, doFetch()]; case 5: throw err_2; case 6: return [2]; } }); }); }; CloudbaseRequest.prototype.send = function (action, data, options, customReqOpts) { if (data === void 0) { data = {}; } if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var response; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.request(action, data, __assign(__assign({}, options), { onUploadProgress: data.onUploadProgress }), customReqOpts)]; case 1: response = _a.sent(); if (response.data.code && this.throwWhenRequestFail) { throw new Error(JSON.stringify({ code: ERRORS.OPERATION_FAIL, msg: "[".concat(response.data.code, "] ").concat(response.data.message), })); } return [2, response.data]; } }); }); }; CloudbaseRequest.prototype.gateWay = function (options, customReqOpts) { var _a; return __awaiter(this, void 0, void 0, function () { var url, name, data, _b, path, method, _c, header, jsonData, requestId, _d, baseUrl, protocol, endpoint, isGetAndHead, dataParse_1, response, _e; var _f; return __generator(this, function (_g) { switch (_g.label) { case 0: url = options.url, name = options.name, data = options.data, _b = options.path, path = _b === void 0 ? '' : _b, method = options.method, _c = options.header, header = _c === void 0 ? {} : _c; if ((!name || !path) && !url) { throw new Error(JSON.stringify({ code: ERRORS.INVALID_PARAMS, msg: '[gateWay] invalid function name or path or url', })); } try { jsonData = data ? JSON.stringify(data) : ''; } catch (e) { throw new Error(JSON.stringify({ code: ERRORS.INVALID_PARAMS, msg: '[gateWay] invalid data', })); } requestId = utilities_1.utils.generateRequestId(); _d = (0, common_1.getEndPointInfo)(this.config.env, 'GATEWAY'), baseUrl = _d.baseUrl, protocol = _d.protocol; endpoint = "".concat(protocol).concat(baseUrl).concat(url || "/".concat(path, "/").concat(name)); isGetAndHead = ['GET', 'HEAD'].includes((_a = method === null || method === void 0 ? void 0 : method.toUpperCase) === null || _a === void 0 ? void 0 : _a.call(method)); if (isGetAndHead) { try { dataParse_1 = {}; try { dataParse_1 = JSON.parse(data); } catch (error) { dataParse_1 = data || {}; } endpoint = "".concat(endpoint).concat(endpoint.includes('?') ? '&' : '?').concat(Object.keys(dataParse_1) .map(function (key) { return "".concat(key, "=").concat(dataParse_1[key]); }) .join('&')); } catch (error) { } } return [4, this.fetch(__assign(__assign({ method: method || 'POST', headers: __assign({ 'Content-Type': 'application/json; charset=utf-8', 'X-Request-Id': requestId }, header) }, (isGetAndHead ? {} : { body: jsonData })), { url: endpoint, customReqOpts: customReqOpts }))]; case 1: response = _g.sent(); _e = [__assign({ requestId: requestId }, response)]; _f = {}; return [4, response.data]; case 2: return [2, __assign.apply(void 0, _e.concat([(_f.data = _g.sent(), _f)]))]; } }); }); }; return CloudbaseRequest; }()); exports.CloudbaseRequest = CloudbaseRequest; var requestMap = {}; function initRequest(config) { requestMap[config.env] = new CloudbaseRequest(__assign(__assign({}, config), { throw: true })); } exports.initRequest = initRequest; function getRequestByEnvId(env) { return requestMap[env]; } exports.getRequestByEnvId = getRequestByEnvId; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWJzL3JlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUFtRztBQVNuRyxrREFBa0U7QUFVbEUsaUNBQXVDO0FBQ3ZDLHFDQUFvQztBQUM1QixJQUFBLE1BQU0sR0FBSyxxQkFBUyxPQUFkLENBQWM7QUFDcEIsSUFBQSxRQUFRLEdBQTRCLGlCQUFLLFNBQWpDLEVBQUUsVUFBVSxHQUFnQixpQkFBSyxXQUFyQixFQUFFLFNBQVMsR0FBSyxpQkFBSyxVQUFWLENBQVU7QUFHakQsSUFBTSwyQkFBMkIsR0FBRztJQUNsQyxhQUFhO0lBQ2IsYUFBYTtJQUNiLHVCQUF1QjtJQUN2Qix3QkFBd0I7SUFDeEIsYUFBYTtJQUNiLHVDQUF1QztJQUN2QyxpQ0FBaUM7SUFDakMsMEJBQTBCO0lBQzFCLDZCQUE2QjtJQUM3Qiw2QkFBNkI7SUFDN0IsMkJBQTJCO0NBQzVCLENBQUE7QUFFRCxTQUFTLFNBQVMsQ0FBQyxRQUE2QixFQUFFLElBQVksRUFBRSxLQUEyQjtJQUN6RixJQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDbkMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsT0FBd0I7UUFDakQsSUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQ2YsSUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFBO1FBQ2xCLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFJO1lBQ1gsSUFBQSxLQUFtRCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBdkUsWUFBWSxVQUFBLEVBQVcsZUFBZSxhQUFpQyxDQUFBO1lBQ3JGLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFB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LEVBQUU7NkJBRWY7eUJBQ0Y7d0JBRWdCLFdBQU0sSUFBSSxDQUFDLEtBQUsscUJBQy9CLE1BQU0sRUFBRSxNQUFNLElBQUksTUFBTSxFQUN4QixPQUFPLGFBQ0wsY0FBYyxFQUFFLGlDQUFpQyxFQUNqRCxjQUFjLEVBQUUsU0FBUyxJQUN0QixNQUFNLEtBRVIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsS0FDM0MsR0FBRyxFQUFFLFFBQVEsRUFDYixhQUFhLGVBQUEsSUFDYixFQUFBOzt3QkFWSSxRQUFRLEdBQUcsU0FVZjt5Q0FFTyxTQUFTLFdBQUEsSUFBSyxRQUFROzt3QkFBUSxXQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUE7NEJBQTFELDhDQUFpQyxPQUFJLEdBQUUsU0FBbUIsVUFBRTs7OztLQUM3RDtJQUNILHVCQUFDO0FBQUQsQ0FBQyxBQTdXRCxJQTZXQztBQTdXWSw0Q0FBZ0I7QUErVzdCLElBQU0sVUFBVSxHQUF5QixFQUFFLENBQUE7QUFFM0MsU0FBZ0IsV0FBVyxDQUFDLE1BQStCO0lBQ3pELFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxnQkFBZ0IsdUJBQ3hDLE1BQU0sS0FDVCxLQUFLLEVBQUUsSUFBSSxJQUNYLENBQUE7QUFDSixDQUFDO0FBTEQsa0NBS0M7QUFFRCxTQUFnQixpQkFBaUIsQ0FBQyxHQUFXO0lBQzNDLE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ3hCLENBQUM7QUFGRCw4Q0FFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERBVEFfVkVSU0lPTiwgZ2V0U2RrVmVyc2lvbiwgZ2V0QmFzZUVuZFBvaW50LCBnZXRFbmRQb2ludEluZm8gfSBmcm9tICcuLi9jb25zdGFudHMvY29tbW9uJ1xuaW1wb3J0IHtcbiAgSVJlcXVlc3RPcHRpb25zLFxuICBTREtSZXF1ZXN0SW50ZXJmYWNlLFxuICBSZXNwb25zZU9iamVjdCxcbiAgSVVwbG9hZFJlcXVlc3RPcHRpb25zLFxuICBJUmVxdWVzdENvbmZpZyxcbiAgSUZldGNoT3B0aW9ucyxcbn0gZnJvbSAnQGNsb3VkYmFzZS9hZGFwdGVyLWludGVyZmFjZSdcbmltcG9ydCB7IHV0aWxzLCBjb25zdGFudHMsIGxhbmdFdmVudCB9IGZyb20gJ0BjbG91ZGJhc2UvdXRpbGl0aWVzJ1xuaW1wb3J0IHsgRW5kUG9pbnRLZXksIEtWIH0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcydcbmltcG9ydCB7IElDdXN0b21SZXFPcHRzIH0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9mdW5jdGlvbnMnXG5pbXBvcnQge1xuICBJR2V0QWNjZXNzVG9rZW5SZXN1bHQsXG4gIElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnLFxuICBJQXBwZW5kZWRSZXF1ZXN0SW5mbyxcbiAgSVJlcXVlc3RCZWZvcmVIb29rLFxufSBmcm9tICdAY2xvdWRiYXNlL3R5cGVzL3JlcXVlc3QnXG5pbXBvcnQgeyBJQ2xvdWRiYXNlQ2FjaGUgfSBmcm9tICdAY2xvdWRiYXNlL3R5cGVzL2NhY2hlJ1xuaW1wb3J0IHsgZ2V0TG9jYWxDYWNoZSB9IGZyb20gJy4vY2FjaGUnXG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJy4vYWRhcHRlcidcbmNvbnN0IHsgRVJST1JTIH0gPSBjb25zdGFudHNcbmNvbnN0IHsgZ2VuU2VxSWQsIGlzRm9ybURhdGEsIGZvcm1hdFVybCB9ID0gdXRpbHNcblxuLy8g5LiL6Z2i5Yeg56eNIGFjdGlvbiDkuI3pnIDopoEgYWNjZXNzIHRva2VuXG5jb25zdCBBQ1RJT05TX1dJVEhPVVRfQUNDRVNTVE9LRU4gPSBbXG4gICdhdXRoLmdldEp3dCcsXG4gICdhdXRoLmxvZ291dCcsXG4gICdhdXRoLnNpZ25JbldpdGhUaWNrZXQnLFxuICAnYXV0aC5zaWduSW5Bbm9ueW1vdXNseScsXG4gICdhdXRoLnNpZ25JbicsXG4gICdhdXRoLmZldGNoQWNjZXNzVG9rZW5XaXRoUmVmcmVzaFRva2VuJyxcbiAgJ2F1dGguc2lnblVwV2l0aEVtYWlsQW5kUGFzc3dvcmQnLFxuICAnYXV0aC5hY3RpdmF0ZUVuZFVzZXJNYWlsJyxcbiAgJ2F1dGguc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCcsXG4gICdhdXRoLnJlc2V0UGFzc3dvcmRXaXRoVG9rZW4nLFxuICAnYXV0aC5pc1VzZXJuYW1lUmVnaXN0ZXJlZCcsXG5dXG5cbmZ1bmN0aW9uIGJpbmRIb29rcyhpbnN0YW5jZTogU0RLUmVxdWVzdEludGVyZmFjZSwgbmFtZTogc3RyaW5nLCBob29rczogSVJlcXVlc3RCZWZvcmVIb29rW10pIHtcbiAgY29uc3Qgb3JpZ2luTWV0aG9kID0gaW5zdGFuY2VbbmFtZV1cbiAgaW5zdGFuY2VbbmFtZV0gPSBmdW5jdGlvbiAob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKSB7XG4gICAgY29uc3QgZGF0YSA9IHt9XG4gICAgY29uc3QgaGVhZGVycyA9IHt9XG4gICAgaG9va3MuZm9yRWFjaCgoaG9vaykgPT4ge1xuICAgICAgY29uc3QgeyBkYXRhOiBhcHBlbmRlZERhdGEsIGhlYWRlcnM6IGFwcGVuZGVkSGVhZGVycyB9ID0gaG9vay5jYWxsKGluc3RhbmNlLCBvcHRpb25zKVxuICAgICAgT2JqZWN0LmFzc2lnbihkYXRhLCBhcHBlbmRlZERhdGEpXG4gICAgICBPYmplY3QuYXNzaWduKGhlYWRlcnMsIGFwcGVuZGVkSGVhZGVycylcbiAgICB9KVxuICAgIGNvbnN0IG9yaWdpbkRhdGEgPSBvcHRpb25zLmRhdGFcbiAgICBvcmlnaW5EYXRhXG4gICAgICAmJiAoKCkgPT4ge1xuICAgICAgICBpZiAoaXNGb3JtRGF0YShvcmlnaW5EYXRhKSkge1xuICAgICAgICAgIE9iamVjdC5rZXlzKGRhdGEpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgKG9yaWdpbkRhdGEgYXMgRm9ybURhdGEpLmFwcGVuZChrZXksIGRhdGFba2V5XSlcbiAgICAgICAgICB9KVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMuZGF0YSA9IHtcbiAgICAgICAgICAuLi5vcmlnaW5EYXRhLFxuICAgICAgICAgIC4uLmRhdGEsXG4gICAgICAgIH1cbiAgICAgIH0pKClcbiAgICBvcHRpb25zLmhlYWRlcnMgPSB7XG4gICAgICAuLi4ob3B0aW9ucy5oZWFkZXJzIHx8IHt9KSxcbiAgICAgIC4uLmhlYWRlcnMsXG4gICAgfVxuICAgIHJldHVybiAob3JpZ2luTWV0aG9kIGFzIEZ1bmN0aW9uKS5jYWxsKGluc3RhbmNlLCBvcHRpb25zKVxuICB9XG59XG5mdW5jdGlvbiBiZWZvcmVFYWNoKCk6IElBcHBlbmRlZFJlcXVlc3RJbmZvIHtcbiAgY29uc3Qgc2VxSWQgPSBnZW5TZXFJZCgpXG4gIHJldHVybiB7XG4gICAgZGF0YToge1xuICAgICAgc2VxSWQsXG4gICAgfSxcbiAgICBoZWFkZXJzOiB7XG4gICAgICAnWC1TREstVmVyc2lvbic6IGBAY2xvdWRiYXNlL2pzLXNkay8ke2dldFNka1ZlcnNpb24oKX1gLFxuICAgICAgJ3gtc2VxaWQnOiBzZXFJZCxcbiAgICB9LFxuICB9XG59XG5leHBvcnQgaW50ZXJmYWNlIElHYXRlV2F5T3B0aW9ucyB7XG4gIG5hbWU/OiBzdHJpbmdcbiAgZGF0YT86IGFueVxuICBwYXRoPzogc3RyaW5nXG4gIG1ldGhvZDogc3RyaW5nXG4gIGhlYWRlcj86IHt9XG4gIHVybD86IHN0cmluZ1xufVxuZXhwb3J0IGludGVyZmFjZSBJQ2xvdWRiYXNlUmVxdWVzdCB7XG4gIHBvc3Q6IChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHVwbG9hZDogKG9wdGlvbnM6IElVcGxvYWRSZXF1ZXN0T3B0aW9ucykgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbiAgZG93bmxvYWQ6IChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHJlcXVlc3Q6IChhY3Rpb246IHN0cmluZywgcGFyYW1zOiBLVjxhbnk+LCBvcHRpb25zPzogS1Y8YW55PikgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbiAgc2VuZDogKGFjdGlvbjogc3RyaW5nLCBkYXRhOiBLVjxhbnk+KSA9PiBQcm9taXNlPGFueT5cbiAgZmV0Y2g6IChvcHRpb25zOiBJRmV0Y2hPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxufVxuXG4vKipcbiAqIEBjbGFzcyBDbG91ZGJhc2VSZXF1ZXN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZGJhc2VSZXF1ZXN0IGltcGxlbWVudHMgSUNsb3VkYmFzZVJlcXVlc3Qge1xuICBjb25maWc6IElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnXG4gIHByaXZhdGUgcmVxQ2xhc3M6IFNES1JlcXVlc3RJbnRlcmZhY2VcbiAgLy8g6K+35rGC5aSx6LSl5piv5ZCm5oqb5Ye6RXJyb3JcbiAgcHJpdmF0ZSB0aHJvd1doZW5SZXF1ZXN0RmFpbCA9IGZhbHNlXG4gIC8vIOaMgeS5heWMluacrOWcsOWtmOWCqFxuICBwcml2YXRlIGxvY2FsQ2FjaGU6IElDbG91ZGJhc2VDYWNoZVxuICAvKipcbiAgICog5Yid5aeL5YyWXG4gICAqIEBwYXJhbSBjb25maWdcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogSUNsb3VkYmFzZVJlcXVlc3RDb25maWcgJiB7IHRocm93PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWdcbiAgICBjb25zdCByZXFDb25maWc6IElSZXF1ZXN0Q29uZmlnICYgeyBhdXRoOiBJQ2xvdWRiYXNlUmVxdWVzdENvbmZpZ1snYXV0aCddIH0gPSB7XG4gICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy50aW1lb3V0LFxuICAgICAgdGltZW91dE1zZzogYFtAY2xvdWRiYXNlL2pzLXNka10g6K+35rGC5ZyoJHt0aGlzLmNvbmZpZy50aW1lb3V0IC8gMTAwMH1z5YaF5pyq5a6M5oiQ77yM5bey5Lit5patYCxcbiAgICAgIHJlc3RyaWN0ZWRNZXRob2RzOiBbJ3Bvc3QnLCAncHV0J10sXG4gICAgICBhdXRoOiBjb25maWcuYXV0aCxcbiAgICB9XG4gICAgdGhpcy5yZXFDbGFzcyA9IG5ldyBQbGF0Zm9ybS5hZGFwdGVyLnJlcUNsYXNzKHJlcUNvbmZpZylcbiAgICB0aGlzLnRocm93V2hlblJlcXVlc3RGYWlsID0gY29uZmlnLnRocm93IHx8IGZhbHNlXG4gICAgdGhpcy5sb2NhbENhY2hlID0gZ2V0TG9jYWxDYWNoZSh0aGlzLmNvbmZpZy5lbnYpXG5cbiAgICBpZiAodGhpcy5jb25maWcuZW5kUG9pbnRNb2RlICE9PSAnR0FURVdBWScpIHtcbiAgICAgIGJpbmRIb29rcyh0aGlzLnJlcUNsYXNzLCAncG9zdCcsIFtiZWZvcmVFYWNoXSlcbiAgICAgIGJpbmRIb29rcyh0aGlzLnJlcUNsYXNzLCAndXBsb2FkJywgW2JlZm9yZUVhY2hdKVxuICAgICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICdkb3dubG9hZCcsIFtiZWZvcmVFYWNoXSlcbiAgICB9XG5cbiAgICBsYW5nRXZlbnQuYnVzLm9uKGxhbmdFdmVudC5MQU5HX0NIQU5HRV9FVkVOVCwgKHBhcmFtcykgPT4ge1xuICAgICAgdGhpcy5jb25maWcuaTE4biA9IHBhcmFtcy5kYXRhPy5pMThuIHx8IHRoaXMuY29uZmlnLmkxOG5cbiAgICB9KVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldEFjY2Vzc1Rva2VuKHRva2VuID0gbnVsbCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcbiAgICBpZiAodG9rZW4gIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRva2VuXG4gICAgfVxuICAgIGNvbnN0IGFwcCA9IHRoaXMuY29uZmlnLl9mcm9tQXBwXG5cbiAgICBpZiAoIWFwcC5vYXV0aEluc3RhbmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3lvdSBjYW5cXCd0IHJlcXVlc3Qgd2l0aG91dCBhdXRoJylcbiAgICB9XG5cbiAgICBjb25zdCB7IG9hdXRoSW5zdGFuY2UgfSA9IGFwcFxuICAgIGNvbnN0IG9hdXRoQ2xpZW50ID0gb2F1dGhJbnN0YW5jZS5vYXV0aDJjbGllbnRcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0T2F1dGhBY2Nlc3NUb2tlblYyKG9hdXRoQ2xpZW50KSkuYWNjZXNzVG9rZW5cbiAgfVxuXG4gIHB1YmxpYyBnZXREZWZhdWx0SGVhZGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgW3RoaXMuY29uZmlnLmkxOG4/LkxBTkdfSEVBREVSX0tFWV06IHRoaXMuY29uZmlnLmkxOG4/LmxhbmcsXG4gICAgICAnWC1TREstVmVyc2lvbic6IGBAY2xvdWRiYXNlL2pzLXNkay8ke2dldFNka1ZlcnNpb24oKX1gLFxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwb3N0KG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucywgY3VzdG9tUmVxT3B0cz86IElDdXN0b21SZXFPcHRzKTogUHJvbWlzZTxSZXNwb25zZU9iamVjdD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMucmVxQ2xhc3MucG9zdCh7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgaGVhZGVyczogeyAuLi5vcHRpb25zLmhlYWRlcnMsIC4uLnRoaXMuZ2V0RGVmYXVsdEhlYWRlcnMoKSB9LFxuICAgICAgY3VzdG9tUmVxT3B0cyxcbiAgICB9KVxuICAgIHJldHVybiByZXNcbiAgfVxuICBwdWJsaWMgYXN5bmMgdXBsb2FkKG9wdGlvbnM6IElVcGxvYWRSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLnVwbG9hZCh7IC4uLm9wdGlvbnMsIGhlYWRlcnM6IHsgLi4ub3B0aW9u