@cloudbase/app
Version:
cloudbase javascript sdk core
445 lines • 56.6 kB
JavaScript
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;
};
import { DATA_VERSION, getSdkVersion, getBaseEndPoint, getEndPointInfo } from '../constants/common';
import { utils, constants, langEvent } from '@cloudbase/utilities';
import { getLocalCache } from './cache';
import { Platform } from './adapter';
var ERRORS = constants.ERRORS;
var genSeqId = utils.genSeqId, isFormData = utils.isFormData, formatUrl = 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(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'],
};
this.reqClass = new Platform.adapter.reqClass(reqConfig);
this.throwWhenRequestFail = config.throw || false;
this.localCache = getLocalCache(this.config.env);
if (this.config.endPointMode !== 'GATEWAY') {
bindHooks(this.reqClass, 'post', [beforeEach]);
bindHooks(this.reqClass, 'upload', [beforeEach]);
bindHooks(this.reqClass, 'download', [beforeEach]);
}
langEvent.bus.on(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(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 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, app, oauthInstance, oauthClient, _c, payload, opts, traceHeader, parse, inQuery, search, formatQuery, endPointMode, url, BASE_URL, PROTOCOL, newUrl, res, resTraceHeader;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
tcbTraceKey = "x-tcb-trace_".concat(this.config.env);
contentType = 'application/x-www-form-urlencoded';
tmpObj = __assign({ action: action, dataVersion: 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;
return [4, this.getOauthAccessTokenV2(oauthClient)];
case 1:
_c.access_token = (_d.sent()).accessToken;
_d.label = 2;
case 2:
if (action === 'storage.uploadFile') {
payload = new FormData();
Object.keys(payload).forEach(function (key) {
if (Object.prototype.hasOwnProperty.call(payload, key) && payload[key] !== undefined) {
payload.append(key, tmpObj[key]);
}
});
contentType = 'multipart/form-data';
}
else {
contentType = 'application/json;charset=UTF-8';
payload = {};
Object.keys(tmpObj).forEach(function (key) {
if (tmpObj[key] !== undefined) {
payload[key] = tmpObj[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 = this.config.endPointMode || 'CLOUD_API';
url = getEndPointInfo(this.config.env, endPointMode);
BASE_URL = url.baseUrl;
PROTOCOL = url.protocol;
if (endPointMode === 'GATEWAY') {
if (action === 'functions.invokeFunction' || /^(storage|database)\./.test(action)) {
BASE_URL = "".concat(BASE_URL.match(/\/\/([^/?#]*)/)[0], "/web");
}
}
if (options.pathname) {
newUrl = formatUrl(PROTOCOL, "".concat((_a = 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 }, 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];
}
});
});
};
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, restOptions, doFetch, result, err_1;
var _this = this;
return __generator(this, function (_k) {
switch (_k.label) {
case 0:
token = options.token, _j = options.headers, headers = _j === void 0 ? {} : _j, restOptions = __rest(options, ["token", "headers"]);
doFetch = function () { return __awaiter(_this, void 0, void 0, function () {
var _a, _b, _c;
var _d, _e;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
_b = (_a = this.reqClass).fetch;
_d = {};
_e = { 'X-SDK-Version': "@cloudbase/js-sdk/".concat(getSdkVersion()) };
_c = "Bearer ".concat;
return [4, this.getAccessToken(token)];
case 1: return [2, _b.apply(_a, [__assign.apply(void 0, [(_d.headers = __assign.apply(void 0, [__assign.apply(void 0, [(_e.Authorization = _c.apply("Bearer ", [_f.sent()]), _e), this.getDefaultHeaders()]), headers]), _d), restOptions])])];
}
});
}); };
_k.label = 1;
case 1:
_k.trys.push([1, 3, , 6]);
return [4, doFetch()];
case 2:
result = _k.sent();
return [2, result];
case 3:
err_1 = _k.sent();
if (!((err_1 === null || err_1 === void 0 ? void 0 : err_1.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_1;
}
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:
_k.sent();
return [2, doFetch()];
case 5: throw err_1;
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) {
return __awaiter(this, void 0, void 0, function () {
var name, data, _a, path, method, _b, header, jsonData, requestId, _c, baseUrl, protocol, endpoint, response, _d;
var _e;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
name = options.name, data = options.data, _a = options.path, path = _a === void 0 ? '' : _a, method = options.method, _b = options.header, header = _b === void 0 ? {} : _b;
if (!name || !path) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: '[gateWay] invalid function name or path',
}));
}
try {
jsonData = data ? JSON.stringify(data) : '';
}
catch (e) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: '[gateWay] invalid data',
}));
}
requestId = utils.generateRequestId();
_c = getEndPointInfo(this.config.env, 'GATEWAY'), baseUrl = _c.baseUrl, protocol = _c.protocol;
endpoint = "".concat(protocol).concat(baseUrl, "/").concat(path, "/").concat(name);
return [4, this.fetch({
method: method || 'POST',
headers: __assign({ 'Content-Type': 'application/json; charset=utf-8', 'X-Request-Id': requestId }, header),
body: jsonData,
url: endpoint,
customReqOpts: customReqOpts,
})];
case 1:
response = _f.sent();
_d = [__assign({ requestId: requestId }, response)];
_e = {};
return [4, response.data];
case 2: return [2, __assign.apply(void 0, _d.concat([(_e.data = _f.sent(), _e)]))];
}
});
});
};
return CloudbaseRequest;
}());
export { CloudbaseRequest };
var requestMap = {};
export function initRequest(config) {
requestMap[config.env] = new CloudbaseRequest(__assign(__assign({}, config), { throw: true }));
}
export function getRequestByEnvId(env) {
return requestMap[env];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWJzL3JlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQVNuRyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQVVsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDNUIsSUFBQSxNQUFNLEdBQUssU0FBUyxPQUFkLENBQWM7QUFDcEIsSUFBQSxRQUFRLEdBQTRCLEtBQUssU0FBakMsRUFBRSxVQUFVLEdBQWdCLEtBQUssV0FBckIsRUFBRSxTQUFTLEdBQUssS0FBSyxVQUFWLENBQVU7QUFHakQsSUFBTSwyQkFBMkIsR0FBRztJQUNsQyxhQUFhO0lBQ2IsYUFBYTtJQUNiLHVCQUF1QjtJQUN2Qix3QkFBd0I7SUFDeEIsYUFBYTtJQUNiLHVDQUF1QztJQUN2QyxpQ0FBaUM7SUFDakMsMEJBQTBCO0lBQzFCLDZCQUE2QjtJQUM3Qiw2QkFBNkI7SUFDN0IsMkJBQTJCO0NBQzVCLENBQUE7QUFFRCxTQUFTLFNBQVMsQ0FBQyxRQUE2QixFQUFFLElBQVksRUFBRSxLQUEyQjtJQUN6RixJQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDbkMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsT0FBd0I7UUFDakQsSUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQ2YsSUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFBO1FBQ2xCLEtBQUssQ0FBQyxPQUFP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QUFFOzs7O0tBQzdEO0lBQ0gsdUJBQUM7QUFBRCxDQUFDLEFBelVELElBeVVDOztBQUVELElBQU0sVUFBVSxHQUF5QixFQUFFLENBQUE7QUFFM0MsTUFBTSxVQUFVLFdBQVcsQ0FBQyxNQUErQjtJQUN6RCxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksZ0JBQWdCLHVCQUN4QyxNQUFNLEtBQ1QsS0FBSyxFQUFFLElBQUksSUFDWCxDQUFBO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxHQUFXO0lBQzNDLE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEQVRBX1ZFUlNJT04sIGdldFNka1ZlcnNpb24sIGdldEJhc2VFbmRQb2ludCwgZ2V0RW5kUG9pbnRJbmZvIH0gZnJvbSAnLi4vY29uc3RhbnRzL2NvbW1vbidcbmltcG9ydCB7XG4gIElSZXF1ZXN0T3B0aW9ucyxcbiAgU0RLUmVxdWVzdEludGVyZmFjZSxcbiAgUmVzcG9uc2VPYmplY3QsXG4gIElVcGxvYWRSZXF1ZXN0T3B0aW9ucyxcbiAgSVJlcXVlc3RDb25maWcsXG4gIElGZXRjaE9wdGlvbnMsXG59IGZyb20gJ0BjbG91ZGJhc2UvYWRhcHRlci1pbnRlcmZhY2UnXG5pbXBvcnQgeyB1dGlscywgY29uc3RhbnRzLCBsYW5nRXZlbnQgfSBmcm9tICdAY2xvdWRiYXNlL3V0aWxpdGllcydcbmltcG9ydCB7IEVuZFBvaW50S2V5LCBLViB9IGZyb20gJ0BjbG91ZGJhc2UvdHlwZXMnXG5pbXBvcnQgeyBJQ3VzdG9tUmVxT3B0cyB9IGZyb20gJ0BjbG91ZGJhc2UvdHlwZXMvZnVuY3Rpb25zJ1xuaW1wb3J0IHtcbiAgSUdldEFjY2Vzc1Rva2VuUmVzdWx0LFxuICBJQ2xvdWRiYXNlUmVxdWVzdENvbmZpZyxcbiAgSUFwcGVuZGVkUmVxdWVzdEluZm8sXG4gIElSZXF1ZXN0QmVmb3JlSG9vayxcbn0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9yZXF1ZXN0J1xuaW1wb3J0IHsgSUNsb3VkYmFzZUNhY2hlIH0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9jYWNoZSdcbmltcG9ydCB7IGdldExvY2FsQ2FjaGUgfSBmcm9tICcuL2NhY2hlJ1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICcuL2FkYXB0ZXInXG5jb25zdCB7IEVSUk9SUyB9ID0gY29uc3RhbnRzXG5jb25zdCB7IGdlblNlcUlkLCBpc0Zvcm1EYXRhLCBmb3JtYXRVcmwgfSA9IHV0aWxzXG5cbi8vIOS4i+mdouWHoOenjSBhY3Rpb24g5LiN6ZyA6KaBIGFjY2VzcyB0b2tlblxuY29uc3QgQUNUSU9OU19XSVRIT1VUX0FDQ0VTU1RPS0VOID0gW1xuICAnYXV0aC5nZXRKd3QnLFxuICAnYXV0aC5sb2dvdXQnLFxuICAnYXV0aC5zaWduSW5XaXRoVGlja2V0JyxcbiAgJ2F1dGguc2lnbkluQW5vbnltb3VzbHknLFxuICAnYXV0aC5zaWduSW4nLFxuICAnYXV0aC5mZXRjaEFjY2Vzc1Rva2VuV2l0aFJlZnJlc2hUb2tlbicsXG4gICdhdXRoLnNpZ25VcFdpdGhFbWFpbEFuZFBhc3N3b3JkJyxcbiAgJ2F1dGguYWN0aXZhdGVFbmRVc2VyTWFpbCcsXG4gICdhdXRoLnNlbmRQYXNzd29yZFJlc2V0RW1haWwnLFxuICAnYXV0aC5yZXNldFBhc3N3b3JkV2l0aFRva2VuJyxcbiAgJ2F1dGguaXNVc2VybmFtZVJlZ2lzdGVyZWQnLFxuXVxuXG5mdW5jdGlvbiBiaW5kSG9va3MoaW5zdGFuY2U6IFNES1JlcXVlc3RJbnRlcmZhY2UsIG5hbWU6IHN0cmluZywgaG9va3M6IElSZXF1ZXN0QmVmb3JlSG9va1tdKSB7XG4gIGNvbnN0IG9yaWdpbk1ldGhvZCA9IGluc3RhbmNlW25hbWVdXG4gIGluc3RhbmNlW25hbWVdID0gZnVuY3Rpb24gKG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucykge1xuICAgIGNvbnN0IGRhdGEgPSB7fVxuICAgIGNvbnN0IGhlYWRlcnMgPSB7fVxuICAgIGhvb2tzLmZvckVhY2goKGhvb2spID0+IHtcbiAgICAgIGNvbnN0IHsgZGF0YTogYXBwZW5kZWREYXRhLCBoZWFkZXJzOiBhcHBlbmRlZEhlYWRlcnMgfSA9IGhvb2suY2FsbChpbnN0YW5jZSwgb3B0aW9ucylcbiAgICAgIE9iamVjdC5hc3NpZ24oZGF0YSwgYXBwZW5kZWREYXRhKVxuICAgICAgT2JqZWN0LmFzc2lnbihoZWFkZXJzLCBhcHBlbmRlZEhlYWRlcnMpXG4gICAgfSlcbiAgICBjb25zdCBvcmlnaW5EYXRhID0gb3B0aW9ucy5kYXRhXG4gICAgb3JpZ2luRGF0YVxuICAgICAgJiYgKCgpID0+IHtcbiAgICAgICAgaWYgKGlzRm9ybURhdGEob3JpZ2luRGF0YSkpIHtcbiAgICAgICAgICBPYmplY3Qua2V5cyhkYXRhKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIChvcmlnaW5EYXRhIGFzIEZvcm1EYXRhKS5hcHBlbmQoa2V5LCBkYXRhW2tleV0pXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLmRhdGEgPSB7XG4gICAgICAgICAgLi4ub3JpZ2luRGF0YSxcbiAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICB9XG4gICAgICB9KSgpXG4gICAgb3B0aW9ucy5oZWFkZXJzID0ge1xuICAgICAgLi4uKG9wdGlvbnMuaGVhZGVycyB8fCB7fSksXG4gICAgICAuLi5oZWFkZXJzLFxuICAgIH1cbiAgICByZXR1cm4gKG9yaWdpbk1ldGhvZCBhcyBGdW5jdGlvbikuY2FsbChpbnN0YW5jZSwgb3B0aW9ucylcbiAgfVxufVxuZnVuY3Rpb24gYmVmb3JlRWFjaCgpOiBJQXBwZW5kZWRSZXF1ZXN0SW5mbyB7XG4gIGNvbnN0IHNlcUlkID0gZ2VuU2VxSWQoKVxuICByZXR1cm4ge1xuICAgIGRhdGE6IHtcbiAgICAgIHNlcUlkLFxuICAgIH0sXG4gICAgaGVhZGVyczoge1xuICAgICAgJ1gtU0RLLVZlcnNpb24nOiBgQGNsb3VkYmFzZS9qcy1zZGsvJHtnZXRTZGtWZXJzaW9uKCl9YCxcbiAgICAgICd4LXNlcWlkJzogc2VxSWQsXG4gICAgfSxcbiAgfVxufVxuZXhwb3J0IGludGVyZmFjZSBJR2F0ZVdheU9wdGlvbnMge1xuICBuYW1lOiBzdHJpbmdcbiAgZGF0YT86IGFueVxuICBwYXRoOiBzdHJpbmdcbiAgbWV0aG9kOiBzdHJpbmdcbiAgaGVhZGVyPzoge31cbn1cbmV4cG9ydCBpbnRlcmZhY2UgSUNsb3VkYmFzZVJlcXVlc3Qge1xuICBwb3N0OiAob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxuICB1cGxvYWQ6IChvcHRpb25zOiBJVXBsb2FkUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIGRvd25sb2FkOiAob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxuICByZXF1ZXN0OiAoYWN0aW9uOiBzdHJpbmcsIHBhcmFtczogS1Y8YW55Piwgb3B0aW9ucz86IEtWPGFueT4pID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHNlbmQ6IChhY3Rpb246IHN0cmluZywgZGF0YTogS1Y8YW55PikgPT4gUHJvbWlzZTxhbnk+XG4gIGZldGNoOiAob3B0aW9uczogSUZldGNoT3B0aW9ucykgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbn1cblxuLyoqXG4gKiBAY2xhc3MgQ2xvdWRiYXNlUmVxdWVzdFxuICovXG5leHBvcnQgY2xhc3MgQ2xvdWRiYXNlUmVxdWVzdCBpbXBsZW1lbnRzIElDbG91ZGJhc2VSZXF1ZXN0IHtcbiAgY29uZmlnOiBJQ2xvdWRiYXNlUmVxdWVzdENvbmZpZ1xuICBwcml2YXRlIHJlcUNsYXNzOiBTREtSZXF1ZXN0SW50ZXJmYWNlXG4gIC8vIOivt+axguWksei0peaYr+WQpuaKm+WHukVycm9yXG4gIHByaXZhdGUgdGhyb3dXaGVuUmVxdWVzdEZhaWwgPSBmYWxzZVxuICAvLyDmjIHkuYXljJbmnKzlnLDlrZjlgqhcbiAgcHJpdmF0ZSBsb2NhbENhY2hlOiBJQ2xvdWRiYXNlQ2FjaGVcbiAgLyoqXG4gICAqIOWIneWni+WMllxuICAgKiBAcGFyYW0gY29uZmlnXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnICYgeyB0aHJvdz86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnXG4gICAgY29uc3QgcmVxQ29uZmlnOiBJUmVxdWVzdENvbmZpZyA9IHtcbiAgICAgIHRpbWVvdXQ6IHRoaXMuY29uZmlnLnRpbWVvdXQsXG4gICAgICB0aW1lb3V0TXNnOiBgW0BjbG91ZGJhc2UvanMtc2RrXSDor7fmsYLlnKgke3RoaXMuY29uZmlnLnRpbWVvdXQgLyAxMDAwfXPlhoXmnKrlrozmiJDvvIzlt7LkuK3mlq1gLFxuICAgICAgcmVzdHJpY3RlZE1ldGhvZHM6IFsncG9zdCcsICdwdXQnXSxcbiAgICB9XG4gICAgdGhpcy5yZXFDbGFzcyA9IG5ldyBQbGF0Zm9ybS5hZGFwdGVyLnJlcUNsYXNzKHJlcUNvbmZpZylcbiAgICB0aGlzLnRocm93V2hlblJlcXVlc3RGYWlsID0gY29uZmlnLnRocm93IHx8IGZhbHNlXG4gICAgdGhpcy5sb2NhbENhY2hlID0gZ2V0TG9jYWxDYWNoZSh0aGlzLmNvbmZpZy5lbnYpXG5cbiAgICBpZiAodGhpcy5jb25maWcuZW5kUG9pbnRNb2RlICE9PSAnR0FURVdBWScpIHtcbiAgICAgIGJpbmRIb29rcyh0aGlzLnJlcUNsYXNzLCAncG9zdCcsIFtiZWZvcmVFYWNoXSlcbiAgICAgIGJpbmRIb29rcyh0aGlzLnJlcUNsYXNzLCAndXBsb2FkJywgW2JlZm9yZUVhY2hdKVxuICAgICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICdkb3dubG9hZCcsIFtiZWZvcmVFYWNoXSlcbiAgICB9XG5cbiAgICBsYW5nRXZlbnQuYnVzLm9uKGxhbmdFdmVudC5MQU5HX0NIQU5HRV9FVkVOVCwgKHBhcmFtcykgPT4ge1xuICAgICAgdGhpcy5jb25maWcuaTE4biA9IHBhcmFtcy5kYXRhPy5pMThuIHx8IHRoaXMuY29uZmlnLmkxOG5cbiAgICB9KVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldEFjY2Vzc1Rva2VuKHRva2VuID0gbnVsbCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcbiAgICBpZiAodG9rZW4gIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRva2VuXG4gICAgfVxuICAgIGNvbnN0IGFwcCA9IHRoaXMuY29uZmlnLl9mcm9tQXBwXG5cbiAgICBpZiAoIWFwcC5vYXV0aEluc3RhbmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3lvdSBjYW5cXCd0IHJlcXVlc3Qgd2l0aG91dCBhdXRoJylcbiAgICB9XG5cbiAgICBjb25zdCB7IG9hdXRoSW5zdGFuY2UgfSA9IGFwcFxuICAgIGNvbnN0IG9hdXRoQ2xpZW50ID0gb2F1dGhJbnN0YW5jZS5vYXV0aDJjbGllbnRcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0T2F1dGhBY2Nlc3NUb2tlblYyKG9hdXRoQ2xpZW50KSkuYWNjZXNzVG9rZW5cbiAgfVxuXG4gIHB1YmxpYyBnZXREZWZhdWx0SGVhZGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgW3RoaXMuY29uZmlnLmkxOG4/LkxBTkdfSEVBREVSX0tFWV06IHRoaXMuY29uZmlnLmkxOG4/LmxhbmcsXG4gICAgICAnWC1TREstVmVyc2lvbic6IGBAY2xvdWRiYXNlL2pzLXNkay8ke2dldFNka1ZlcnNpb24oKX1gLFxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwb3N0KG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucywgY3VzdG9tUmVxT3B0cz86IElDdXN0b21SZXFPcHRzKTogUHJvbWlzZTxSZXNwb25zZU9iamVjdD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMucmVxQ2xhc3MucG9zdCh7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgaGVhZGVyczogeyAuLi5vcHRpb25zLmhlYWRlcnMsIC4uLnRoaXMuZ2V0RGVmYXVsdEhlYWRlcnMoKSB9LFxuICAgICAgY3VzdG9tUmVxT3B0cyxcbiAgICB9KVxuICAgIHJldHVybiByZXNcbiAgfVxuICBwdWJsaWMgYXN5bmMgdXBsb2FkKG9wdGlvbnM6IElVcGxvYWRSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLnVwbG9hZCh7IC4uLm9wdGlvbnMsIGhlYWRlcnM6IHsgLi4ub3B0aW9ucy5oZWFkZXJzLCAuLi50aGlzLmdldERlZmF1bHRIZWFkZXJzKCkgfSB9KVxuICAgIHJldHVybiByZXNcbiAgfVxuICBwdWJsaWMgYXN5bmMgZG93bmxvYWQob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZU9iamVjdD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMucmVxQ2xhc3MuZG93bmxvYWQoe1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGhlYWRlcnM6IHsgLi4ub3B0aW9ucy5oZWFkZXJzLCAuLi50aGlzLmdldERlZmF1bHRIZWFkZXJzKCkgfSxcbiAgICB9KVxuICAgIHJldHVybiByZXNcbiAgfVxuXG4gIHB1YmxpYyBnZXRCYXNlRW5kUG9pbnQoZW5kUG9pbnRLZXk6IEVuZFBvaW50S2V5ID0gJ0NMT1VEX0FQSScpIHtcbiAgICByZXR1cm4gZ2V0QmFzZUVuZFBvaW50KHRoaXMuY29uZmlnLmVudiwgZW5kUG9pbnRLZXkpXG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0T2F1dGhBY2Nlc3NUb2tlblYyKG9hdXRoQ2xpZW50OiBhbnkpOiBQcm9taXNlPElHZXRBY2Nlc3NUb2tlblJlc3VsdD4ge1xuICAgIGNvbnN0IHZhbGlkQWNjZXNzVG9rZW4gPSBhd2FpdCBvYXV0aENsaWVudC5nZXRBY2Nlc3NUb2tlbigpXG4gICAgY29uc3QgY3JlZGVudGlhbHMgPSBhd2FpdCBvYXV0aENsaWVudC5nZXRDcmVkZW50aWFscygpXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjY2Vzc1Rva2VuOiB2YWxpZEFjY2Vzc1Rva2VuLFxuICAgICAgYWNjZXNzVG9rZW5FeHBpcmU6IG5ldyBEYXRlKGNyZWRlbnRpYWxzLmV4cGlyZXNfYXQpLmdldFRpbWUoKSxcbiAgICB9XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG4gIHB1YmxpYyBhc3luYyByZXF1ZXN0KFxuICAgIGFjdGlvbjogc3RyaW5nLFxuICAgIHBhcmFtczogS1Y8YW55PixcbiAgICBvcHRpb25zPzoge1xuICAgICAgb25VcGxvYWRQcm9ncmVzcz86IEZ1bmN0aW9uXG4gICAgICBwYXRobmFtZT86IHN0cmluZ1xuICAgICAgcGFyc2U/OiBib29sZWFuXG4gICAgICBpblF1ZXJ5PzogS1Y8YW55PlxuICAgICAgc2VhcmNoPzogc3RyaW5nXG4gICAgICBkZWZhdWx0UXVlcnk/OiBLVjxhbnk+XG4gICAgICBoZWFkZXJzPzogS1Y8c3RyaW5nPlxuICAgIH0sXG4gICAgY3VzdG9tUmVxT3B0cz86IElDdXN0b21SZXFPcHRzLFxuICApOiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PiB7XG4gICAgY29uc3QgdGNiVHJhY2VLZXkgPSBgeC10Y2ItdHJhY2VfJHt0aGlzLmNvbmZpZy5lbnZ9YFxuICAgIGxldCBjb250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG5cbiAgICBjb25zdCB0bXBPYmo6IEtWPGFueT4gPSB7XG4gICAgICBhY3Rpb24sXG4gICAgICBkYXRhVmVyc2lvbjogREFUQV9WRVJTSU9OLFxuICAgICAgZW52OiB0aGlzLmNvbmZpZy5lbnYsXG4gICAgICAuLi5wYXJhbXMsXG4gICAgfVxuXG4gICAgaWYgKEFDVElPTlNfV0lUSE9VVF9BQ0NFU1NUT0tFTi5pbmRleE9mKGFjdGlvbikgPT09IC0xKSB7XG4gICAgICBjb25zdCBhcHAgPSB0aGlzLmNvbmZpZy5fZnJvbUFwcFxuXG4gICAgICBpZiAoIWFwcC5vYXV0aEluc3RhbmNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigneW91IGNhblxcJ3QgcmVxdWVzdCB3aXRob3V0IGF1dGgnKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IG9hdXRoSW5zdGFuY2UgfSA9IGFwcFxuICAgICAgY29uc3Qgb2F1dGhDbGllbnQgPSBvYXV0aEluc3RhbmNlLm9hdXRoMmNsaWVudFxuICAgICAgdG1wT2JqLmFjY2Vzc190b2tlbiA9IChhd2FpdCB0aGlzLmdldE9hdXRoQWNjZXNzVG9rZW5WMihvYXV0aENsaWVudCkpLmFjY2Vzc1Rva2VuXG4gICAgfVxuXG4gICAgLy8g5ou8Ym9keeWSjGNvbnRlbnQtdHlwZVxuICAgIGxldCBwYXlsb2FkXG4gICAgaWYgKGFjdGlvbiA9PT0gJ3N0b3JhZ2UudXBsb2FkRmlsZScpIHtcbiAgICAgIHBheWxvYWQgPSBuZXcgRm9ybURhdGEoKVxuICAgICAgT2JqZWN0LmtleXMocGF5bG9hZCkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGF5bG9hZCwga2V5KSAmJiBwYXlsb2FkW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHBheWxvYWQuYXBwZW5kKGtleSwgdG1wT2JqW2tleV0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBjb250ZW50VHlwZSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJ1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9VVRGLTgnXG4gICAgICBwYXlsb2FkID0ge31cbiAgICAgIE9iamVjdC5rZXlzKHRtcE9iaikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmICh0bXBPYmpba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGF5bG9hZFtrZXldID0gdG1wT2JqW2tleV1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gICAgY29uc3Qgb3B0czogYW55ID0ge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogY29udGVudFR5cGUsXG4gICAgICAgIC4uLnRoaXMuZ2V0RGVmYXVsdEhlYWRlcnMoKSxcbiAgICAgICAgLi4ub3B0aW9ucz8uaGVhZGVycyxcbiAgICAgIH0sXG4gICAgfVxuICAgIGlmIChvcHRpb25zPy5vblVwbG9hZFByb2dyZXNzKSB7XG4gICAgICBvcHRzLm9uVXBsb2FkUHJvZ3Jlc3MgPSBvcHRpb25zLm9uVXBsb2FkUHJvZ3Jlc3NcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcucmVnaW9uKSB7XG4gICAgICBvcHRzLmhlYWRlcnNbJ1gtVENCLVJlZ2lvbiddID0gdGhpcy5jb25maWcucmVnaW9uXG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2VIZWFkZXIgPSB0aGlzLmxvY2FsQ2FjaGUuZ2V0U3RvcmUodGNiVHJhY2VLZXkpXG4gICAgaWYgKHRyYWNlSGVhZGVyKSB7XG4gICAgICBvcHRzLmhlYWRlcnNbJ1gtVENCLVRyYWNlJ10gPSB0cmFjZUhlYWRlclxuICAgIH1cblxuICAgIC8vIOWPkeWHuuivt+axglxuICAgIC8vIOaWsOeahCB1cmwg6ZyA6KaB5pC65bimIGVudiDlj4LmlbDov5vooYwgQ09SUyDmoKHpqoxcbiAgICAvLyDor7fmsYLpk77mjqXmlK/mjIHmt7vliqDliqjmgIEgcXVlcnkg5Y+C5pWw77yM5pa55L6/55So5oi36LCD6K+V5a6a5L2N6K+35rGCXG4gICAgY29uc3QgcGFyc2UgPSBvcHRpb25zPy5wYXJzZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5wYXJzZSA6IHBhcmFtcy5wYXJzZVxuICAgIGNvbnN0IGluUXVlcnkgPSBvcHRpb25zPy5pblF1ZXJ5ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmluUXVlcnkgOiBwYXJhbXMuaW5RdWVyeVxuICAgIGNvbnN0IHNlYXJjaCA9IG9wdGlvbnM/LnNlYXJjaCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zZWFyY2ggO