j2s
Version:
JSON to SQL, build RESTful API server on the fly, which accespts JSON describing SQL query statements, support (almost) full SQL functionality, with configurable access control & pluggable middlewares
767 lines (587 loc) • 64 kB
JavaScript
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getRelationNames = getRelationNames;
exports.modifyRelation = modifyRelation;
var _isPlainObject = _interopRequireDefault(require("lodash/isPlainObject"));
var _isArray = _interopRequireDefault(require("lodash/isArray"));
var _isNumber = _interopRequireDefault(require("lodash/isNumber"));
var _pickBy = _interopRequireDefault(require("lodash/pickBy"));
var _every = _interopRequireDefault(require("lodash/every"));
var _has = _interopRequireDefault(require("lodash/has"));
var _map = _interopRequireDefault(require("lodash/map"));
var errors = _interopRequireWildcard(require("./errors"));
var _bluebird = _interopRequireDefault(require("bluebird"));
var _core = require("./core");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function getRelationNames(bookshelf, instance, model) {
var names = [];
var _iterator = _createForOfIteratorHelper(Object.getOwnPropertyNames(Object.getPrototypeOf(instance))),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var name = _step.value;
var method = instance[name];
if (!(method instanceof Function) || method === model) continue;
names.push(name);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return names;
} // TODO: access control on relations
function modifyRelation(_x, _x2, _x3, _x4, _x5, _x6, _x7, _x8) {
return _modifyRelation.apply(this, arguments);
}
function _modifyRelation() {
_modifyRelation = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(ctx, bookshelf, instance, model, relationName, payload, transacting, allOpts) {
var relation, relatedData, relationType, foreignKey, targetIdAttribute, targetModel, parentIdAttribute, relationOpts, key, relInstance, checked, _relInstance, _checked, foreignAttribute, foreignInstance, _checked2, foreignInstances, i, id, inst, _checked3, _foreignInstances, _i, _id, _inst, _checked4, _foreignInstances2, _checked5, _foreignInstances3, _i2, _id2, _inst2, _checked6, joinTableOpts, joinModel, relationPayload, relationInstances, _checked7, _relationInstances, _checked8, _foreignInstances4, _checked9, _relationInstances2, _checked10, _relationPayload;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
relation = instance[relationName]();
relatedData = relation.relatedData;
relationType = relatedData.type;
foreignKey = relatedData.foreignKey;
targetIdAttribute = relatedData.targetIdAttribute;
targetModel = relatedData.target;
parentIdAttribute = instance.get(instance.idAttribute);
relationOpts = null;
_context.t0 = regeneratorRuntime.keys(allOpts);
case 9:
if ((_context.t1 = _context.t0()).done) {
_context.next = 16;
break;
}
key = _context.t1.value;
if (!(allOpts[key].model == targetModel)) {
_context.next = 14;
break;
}
relationOpts = allOpts[key];
return _context.abrupt("break", 16);
case 14:
_context.next = 9;
break;
case 16:
if (!(relationType === 'hasOne' || relationType === 'morphOne')) {
_context.next = 43;
break;
}
if (!(0, _isNumber["default"])(payload)) {
_context.next = 28;
break;
}
_context.next = 20;
return targetModel.where(_defineProperty({}, targetIdAttribute, payload)).save(_defineProperty({}, foreignKey, parentIdAttribute), {
transacting: transacting,
method: 'update',
patch: true,
require: true
});
case 20:
relInstance = _context.sent;
_context.next = 23;
return (0, _core.check)(ctx, relationOpts.identity.U, relationOpts.admin.U, relInstance, relationOpts.access.U);
case 23:
checked = _context.sent;
if (checked) {
_context.next = 26;
break;
}
throw errors.ErrOperationNotAuthorized;
case 26:
_context.next = 41;
break;
case 28:
if (!(0, _isPlainObject["default"])(payload)) {
_context.next = 40;
break;
}
payload[foreignKey] = parentIdAttribute;
_context.next = 32;
return targetModel.forge(payload).save(null, {
transacting: transacting,
method: 'insert'
});
case 32:
_relInstance = _context.sent;
_context.next = 35;
return (0, _core.check)(ctx, relationOpts.identity.C, relationOpts.admin.C, _relInstance, relationOpts.access.C);
case 35:
_checked = _context.sent;
if (_checked) {
_context.next = 38;
break;
}
throw errors.ErrOperationNotAuthorized;
case 38:
_context.next = 41;
break;
case 40:
throw errors.FnErrValueShouldBeNumberOrObject(relationName);
case 41:
_context.next = 224;
break;
case 43:
if (!(relationType === 'belongsTo' || relationType === 'morphTo')) {
_context.next = 66;
break;
}
foreignAttribute = null;
if (!(0, _isNumber["default"])(payload)) {
_context.next = 49;
break;
}
foreignAttribute = payload;
_context.next = 62;
break;
case 49:
if (!(0, _isPlainObject["default"])(payload)) {
_context.next = 61;
break;
}
_context.next = 52;
return targetModel.forge(payload).save(null, {
transacting: transacting,
method: 'insert'
});
case 52:
foreignInstance = _context.sent;
_context.next = 55;
return (0, _core.check)(ctx, relationOpts.identity.C, relationOpts.admin.C, foreignInstance, relationOpts.access.C);
case 55:
_checked2 = _context.sent;
if (_checked2) {
_context.next = 58;
break;
}
throw errors.ErrOperationNotAuthorized;
case 58:
foreignAttribute = foreignInstance.get(foreignInstance.idAttribute);
_context.next = 62;
break;
case 61:
throw errors.FnErrValueShouldBeNumberOrObject(relationName);
case 62:
_context.next = 64;
return instance.save(_defineProperty({}, foreignKey, foreignAttribute), {
transacting: transacting,
method: 'update',
patch: true,
require: true
});
case 64:
_context.next = 224;
break;
case 66:
if (!(relationType === 'hasMany' || relationType === 'morphMany')) {
_context.next = 145;
break;
}
if ((0, _isPlainObject["default"])(payload)) {
_context.next = 69;
break;
}
throw errors.FnErrValueShouldBeObject(relationName);
case 69:
if (!(0, _has["default"])(payload, 'add')) {
_context.next = 88;
break;
}
if ((0, _isArray["default"])(payload.add)) {
_context.next = 72;
break;
}
throw errors.FnErrValueShouldBeArray('add');
case 72:
foreignInstances = [];
i = 0;
case 74:
if (!(i < payload.add.length)) {
_context.next = 83;
break;
}
id = payload.add[i];
_context.next = 78;
return targetModel.where(_defineProperty({}, targetIdAttribute, id)).save(_defineProperty({}, foreignKey, parentIdAttribute), {
transacting: transacting,
method: 'update',
patch: true,
require: true
});
case 78:
inst = _context.sent;
foreignInstances.push(inst);
case 80:
i++;
_context.next = 74;
break;
case 83:
_context.next = 85;
return (0, _core.check)(ctx, relationOpts.identity.U, relationOpts.admin.U, foreignInstances, relationOpts.access.U);
case 85:
_checked3 = _context.sent;
if (_checked3) {
_context.next = 88;
break;
}
throw errors.ErrOperationNotAuthorized;
case 88:
if (!(0, _has["default"])(payload, 'remove')) {
_context.next = 107;
break;
}
if ((0, _isArray["default"])(payload.remove)) {
_context.next = 91;
break;
}
throw errors.FnErrValueShouldBeArray('remove');
case 91:
_foreignInstances = [];
_i = 0;
case 93:
if (!(_i < payload.remove.length)) {
_context.next = 102;
break;
}
_id = payload.remove[_i];
_context.next = 97;
return targetModel.where(_defineProperty({}, targetIdAttribute, _id)).save(_defineProperty({}, foreignKey, null), {
transacting: transacting,
method: 'update',
patch: true,
require: true
});
case 97:
_inst = _context.sent;
_foreignInstances.push(_inst);
case 99:
_i++;
_context.next = 93;
break;
case 102:
_context.next = 104;
return (0, _core.check)(ctx, relationOpts.identity.U, relationOpts.admin.U, _foreignInstances, relationOpts.access.U);
case 104:
_checked4 = _context.sent;
if (_checked4) {
_context.next = 107;
break;
}
throw errors.ErrOperationNotAuthorized;
case 107:
if (!(0, _has["default"])(payload, 'create')) {
_context.next = 118;
break;
}
if ((0, _isArray["default"])(payload.create)) {
_context.next = 110;
break;
}
throw errors.FnErrValueShouldBeArray('create');
case 110:
_context.next = 112;
return _bluebird["default"].map(payload.create, function (obj) {
return relation.create(obj, {
transacting: transacting
});
});
case 112:
_foreignInstances2 = _context.sent;
_context.next = 115;
return (0, _core.check)(ctx, relationOpts.identity.C, relationOpts.admin.C, _foreignInstances2, relationOpts.access.C);
case 115:
_checked5 = _context.sent;
if (_checked5) {
_context.next = 118;
break;
}
throw errors.ErrOperationNotAuthorized;
case 118:
if (!(0, _has["default"])(payload, 'replace')) {
_context.next = 143;
break;
}
if (!((0, _has["default"])(payload, 'add') || (0, _has["default"])(payload, 'remove') || (0, _has["default"])(payload, 'create'))) {
_context.next = 121;
break;
}
throw errors.ErrRelationKeyConflicts;
case 121:
if ((0, _isArray["default"])(payload.replace)) {
_context.next = 123;
break;
}
throw errors.FnErrValueShouldBeArray('replace');
case 123:
_context.next = 125;
return relation.fetch();
case 125:
_foreignInstances3 = _context.sent;
_context.next = 128;
return _foreignInstances3.invokeThen('save', _defineProperty({}, foreignKey, null), {
transacting: transacting,
method: 'update',
patch: true,
require: true
});
case 128:
_i2 = 0;
case 129:
if (!(_i2 < payload.replace.length)) {
_context.next = 138;
break;
}
_id2 = payload.replace[_i2];
_context.next = 133;
return targetModel.where(_defineProperty({}, targetIdAttribute, _id2)).save(_defineProperty({}, foreignKey, parentIdAttribute), {
transacting: transacting,
method: 'update',
patch: true,
require: true
});
case 133:
_inst2 = _context.sent;
_foreignInstances3.push(_inst2);
case 135:
_i2++;
_context.next = 129;
break;
case 138:
_context.next = 140;
return (0, _core.check)(ctx, relationOpts.identity.U, relationOpts.admin.U, _foreignInstances3, relationOpts.access.U);
case 140:
_checked6 = _context.sent;
if (_checked6) {
_context.next = 143;
break;
}
throw errors.ErrOperationNotAuthorized;
case 143:
_context.next = 224;
break;
case 145:
if (!(relationType === 'belongsToMany')) {
_context.next = 223;
break;
}
joinTableOpts = null;
_context.t2 = regeneratorRuntime.keys(allOpts);
case 148:
if ((_context.t3 = _context.t2()).done) {
_context.next = 155;
break;
}
key = _context.t3.value;
if (!(allOpts[key].tableName == relatedData.joinTableName)) {
_context.next = 153;
break;
}
joinTableOpts = allOpts[key];
return _context.abrupt("break", 155);
case 153:
_context.next = 148;
break;
case 155:
joinModel = joinTableOpts.model;
if ((0, _isPlainObject["default"])(payload)) {
_context.next = 158;
break;
}
throw errors.FnErrValueShouldBeNumberOrObject(relationName);
case 158:
if (!(0, _has["default"])(payload, 'add')) {
_context.next = 170;
break;
}
if ((0, _isArray["default"])(payload.add)) {
_context.next = 161;
break;
}
throw errors.FnErrValueShouldBeArray('add');
case 161:
relationPayload = (0, _map["default"])(payload.add, function (id) {
var _ref;
return _ref = {}, _defineProperty(_ref, relatedData.otherKey, id), _defineProperty(_ref, relatedData.foreignKey, instance.get(relatedData.parentIdAttribute)), _ref;
});
_context.next = 164;
return _bluebird["default"].map(relationPayload, function (payload) {
return joinModel.forge(payload).save(null, {
transacting: transacting,
method: 'insert',
patch: false,
require: true
});
});
case 164:
relationInstances = _context.sent;
_context.next = 167;
return (0, _core.check)(ctx, joinTableOpts.identity.C, joinTableOpts.admin.C, relationInstances, joinTableOpts.access.C);
case 167:
_checked7 = _context.sent;
if (_checked7) {
_context.next = 170;
break;
}
throw errors.ErrOperationNotAuthorized;
case 170:
if (!(0, _has["default"])(payload, 'remove')) {
_context.next = 185;
break;
}
if ((0, _isArray["default"])(payload.remove)) {
_context.next = 173;
break;
}
throw errors.FnErrValueShouldBeArray('remove');
case 173:
_context.next = 175;
return joinModel.query(function (qb) {
qb.where(_defineProperty({}, relatedData.foreignKey, instance.get(relatedData.parentIdAttribute))).whereIn(relatedData.otherKey, payload.remove);
}).fetchAll();
case 175:
_relationInstances = _context.sent;
if (!(_relationInstances.length == 0)) {
_context.next = 178;
break;
}
throw errors.ErrResourceNotFound;
case 178:
_context.next = 180;
return (0, _core.check)(ctx, joinTableOpts.identity.D, joinTableOpts.admin.D, _relationInstances, joinTableOpts.access.D);
case 180:
_checked8 = _context.sent;
if (_checked8) {
_context.next = 183;
break;
}
throw errors.ErrOperationNotAuthorized;
case 183:
_context.next = 185;
return _relationInstances.invokeThen('destroy', {
transacting: transacting
});
case 185:
if (!(0, _has["default"])(payload, 'create')) {
_context.next = 196;
break;
}
if ((0, _isArray["default"])(payload.create)) {
_context.next = 188;
break;
}
throw errors.FnErrValueShouldBeArray('create');
case 188:
_context.next = 190;
return _bluebird["default"].map(payload.create, function (obj) {
return relation.create(obj, {
transacting: transacting
});
});
case 190:
_foreignInstances4 = _context.sent;
_context.next = 193;
return (0, _core.check)(ctx, relationOpts.identity.C, relationOpts.admin.C, _foreignInstances4, relationOpts.access.C);
case 193:
_checked9 = _context.sent;
if (_checked9) {
_context.next = 196;
break;
}
throw errors.ErrOperationNotAuthorized;
case 196:
if (!(0, _has["default"])(payload, 'replace')) {
_context.next = 221;
break;
}
if (!((0, _has["default"])(payload, 'add') || (0, _has["default"])(payload, 'remove') || (0, _has["default"])(payload, 'create'))) {
_context.next = 199;
break;
}
throw errors.ErrRelationKeyConflicts;
case 199:
if ((0, _isArray["default"])(payload.replace)) {
_context.next = 201;
break;
}
throw errors.FnErrValueShouldBeArray('replace');
case 201:
_context.next = 203;
return joinModel.query(function (qb) {
qb.where(_defineProperty({}, relatedData.foreignKey, instance.get(relatedData.parentIdAttribute)));
}).fetchAll();
case 203:
_relationInstances2 = _context.sent;
_context.next = 206;
return (0, _core.check)(ctx, joinTableOpts.identity.D, joinTableOpts.admin.D, _relationInstances2, joinTableOpts.access.D);
case 206:
_checked10 = _context.sent;
if (_checked10) {
_context.next = 209;
break;
}
throw errors.ErrOperationNotAuthorized;
case 209:
_context.next = 211;
return _relationInstances2.invokeThen('destroy', {
transacting: transacting
});
case 211:
_relationPayload = null;
if ((0, _every["default"])(payload.replace, _isPlainObject["default"])) {
_relationPayload = payload.replace;
} else {
_relationPayload = (0, _map["default"])(payload.replace, function (id) {
var _ref2;
return _ref2 = {}, _defineProperty(_ref2, relatedData.otherKey, id), _defineProperty(_ref2, relatedData.foreignKey, instance.get(relatedData.parentIdAttribute)), _ref2;
});
}
_context.next = 215;
return _bluebird["default"].map(_relationPayload, function (payload) {
return joinModel.forge(payload).save(null, {
transacting: transacting,
method: 'insert',
patch: false,
require: true
});
});
case 215:
_relationInstances2 = _context.sent;
_context.next = 218;
return (0, _core.check)(ctx, joinTableOpts.identity.C, joinTableOpts.admin.C, _relationInstances2, joinTableOpts.access.C);
case 218:
_checked10 = _context.sent;
if (_checked10) {
_context.next = 221;
break;
}
throw errors.ErrOperationNotAuthorized;
case 221:
_context.next = 224;
break;
case 223:
throw errors.FnErrUnknownRelationType(relationType);
case 224:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return _modifyRelation.apply(this, arguments);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZWxhdGlvbi5qcyJdLCJuYW1lcyI6WyJnZXRSZWxhdGlvbk5hbWVzIiwiYm9va3NoZWxmIiwiaW5zdGFuY2UiLCJtb2RlbCIsIm5hbWVzIiwiT2JqZWN0IiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsImdldFByb3RvdHlwZU9mIiwibmFtZSIsIm1ldGhvZCIsIkZ1bmN0aW9uIiwicHVzaCIsIm1vZGlmeVJlbGF0aW9uIiwiY3R4IiwicmVsYXRpb25OYW1lIiwicGF5bG9hZCIsInRyYW5zYWN0aW5nIiwiYWxsT3B0cyIsInJlbGF0aW9uIiwicmVsYXRlZERhdGEiLCJyZWxhdGlvblR5cGUiLCJ0eXBlIiwiZm9yZWlnbktleSIsInRhcmdldElkQXR0cmlidXRlIiwidGFyZ2V0TW9kZWwiLCJ0YXJnZXQiLCJwYXJlbnRJZEF0dHJpYnV0ZSIsImdldCIsImlkQXR0cmlidXRlIiwicmVsYXRpb25PcHRzIiwia2V5Iiwid2hlcmUiLCJzYXZlIiwicGF0Y2giLCJyZXF1aXJlIiwicmVsSW5zdGFuY2UiLCJpZGVudGl0eSIsIlUiLCJhZG1pbiIsImFjY2VzcyIsImNoZWNrZWQiLCJlcnJvcnMiLCJFcnJPcGVyYXRpb25Ob3RBdXRob3JpemVkIiwiZm9yZ2UiLCJDIiwiRm5FcnJWYWx1ZVNob3VsZEJlTnVtYmVyT3JPYmplY3QiLCJmb3JlaWduQXR0cmlidXRlIiwiZm9yZWlnbkluc3RhbmNlIiwiRm5FcnJWYWx1ZVNob3VsZEJlT2JqZWN0IiwiYWRkIiwiRm5FcnJWYWx1ZVNob3VsZEJlQXJyYXkiLCJmb3JlaWduSW5zdGFuY2VzIiwiaSIsImxlbmd0aCIsImlkIiwiaW5zdCIsInJlbW92ZSIsImNyZWF0ZSIsIlByb21pc2UiLCJtYXAiLCJvYmoiLCJFcnJSZWxhdGlvbktleUNvbmZsaWN0cyIsInJlcGxhY2UiLCJmZXRjaCIsImludm9rZVRoZW4iLCJqb2luVGFibGVPcHRzIiwidGFibGVOYW1lIiwiam9pblRhYmxlTmFtZSIsImpvaW5Nb2RlbCIsInJlbGF0aW9uUGF5bG9hZCIsIm90aGVyS2V5IiwicmVsYXRpb25JbnN0YW5jZXMiLCJxdWVyeSIsInFiIiwid2hlcmVJbiIsImZldGNoQWxsIiwiRXJyUmVzb3VyY2VOb3RGb3VuZCIsIkQiLCJpc1BsYWluT2JqZWN0IiwiRm5FcnJVbmtub3duUmVsYXRpb25UeXBlIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVPLFNBQVNBLGdCQUFULENBQTBCQyxTQUExQixFQUFxQ0MsUUFBckMsRUFBK0NDLEtBQS9DLEVBQXNEO0FBQ3pELE1BQUlDLEtBQUssR0FBRyxFQUFaOztBQUR5RCw2Q0FFeENDLE1BQU0sQ0FBQ0MsbUJBQVAsQ0FBMkJELE1BQU0sQ0FBQ0UsY0FBUCxDQUFzQkwsUUFBdEIsQ0FBM0IsQ0FGd0M7QUFBQTs7QUFBQTtBQUV6RCx3REFBOEU7QUFBQSxVQUFyRU0sSUFBcUU7QUFDMUUsVUFBSUMsTUFBTSxHQUFHUCxRQUFRLENBQUNNLElBQUQsQ0FBckI7QUFDQSxVQUFJLEVBQUVDLE1BQU0sWUFBWUMsUUFBcEIsS0FBaUNELE1BQU0sS0FBS04sS0FBaEQsRUFBdUQ7QUFDdkRDLE1BQUFBLEtBQUssQ0FBQ08sSUFBTixDQUFXSCxJQUFYO0FBQ0g7QUFOd0Q7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFPekQsU0FBT0osS0FBUDtBQUNILEMsQ0FFRDs7O1NBQ3NCUSxjOzs7Ozs0RUFBZixpQkFBOEJDLEdBQTlCLEVBQW1DWixTQUFuQyxFQUE4Q0MsUUFBOUMsRUFBd0RDLEtBQXhELEVBQStEVyxZQUEvRCxFQUE2RUMsT0FBN0UsRUFBc0ZDLFdBQXRGLEVBQW1HQyxPQUFuRztBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0NDLFlBQUFBLFFBREQsR0FDWWhCLFFBQVEsQ0FBQ1ksWUFBRCxDQUFSLEVBRFo7QUFFQ0ssWUFBQUEsV0FGRCxHQUVlRCxR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QWQsQ0FBdUJRLENBQWxDLEVBQXFDcUIsYUFBYSxDQUFDM0IsS0FBZCxDQUFvQk0sQ0FBekQsRUFBNEQyQixtQkFBNUQsRUFBK0VOLGFBQWEsQ0FBQzFCLE1BQWQsQ0FBcUJLLENBQXBHLENBOVNyQjs7QUFBQTtBQThTS0osWUFBQUEsVUE5U0w7O0FBQUEsZ0JBK1NVQSxVQS9TVjtBQUFBO0FBQUE7QUFBQTs7QUFBQSxrQkFnVGVDLE1BQU0sQ0FBQ0MseUJBaFR0Qjs7QUFBQTtBQUFBO0FBQUE7O0FBQUE7QUFBQSxrQkFvVE9ELE1BQU0sQ0FBQ3NDLHdCQUFQLENBQWdDM0QsWUFBaEMsQ0FwVFA7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGlzUGxhaW5PYmplY3QgZnJvbSAnbG9kYXNoL2lzUGxhaW5PYmplY3QnO1xuaW1wb3J0IGlzQXJyYXkgZnJvbSAnbG9kYXNoL2lzQXJyYXknO1xuaW1wb3J0IGlzTnVtYmVyIGZyb20gJ2xvZGFzaC9pc051bWJlcic7XG5pbXBvcnQgcGlja0J5IGZyb20gJ2xvZGFzaC9waWNrQnknO1xuaW1wb3J0IGV2ZXJ5IGZyb20gJ2xvZGFzaC9ldmVyeSc7XG5pbXBvcnQgaGFzIGZyb20gJ2xvZGFzaC9oYXMnO1xuaW1wb3J0IG1hcCBmcm9tICdsb2Rhc2gvbWFwJztcbmltcG9ydCAqIGFzIGVycm9ycyBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgUHJvbWlzZSBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQge2NoZWNrLCBxdWVyeX0gZnJvbSAnLi9jb3JlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlbGF0aW9uTmFtZXMoYm9va3NoZWxmLCBpbnN0YW5jZSwgbW9kZWwpIHtcbiAgICBsZXQgbmFtZXMgPSBbXTtcbiAgICBmb3IgKGxldCBuYW1lIG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnN0YW5jZSkpKSB7XG4gICAgICAgIGxldCBtZXRob2QgPSBpbnN0YW5jZVtuYW1lXTtcbiAgICAgICAgaWYgKCEobWV0aG9kIGluc3RhbmNlb2YgRnVuY3Rpb24pIHx8IG1ldGhvZCA9PT0gbW9kZWwpIGNvbnRpbnVlO1xuICAgICAgICBuYW1lcy5wdXNoKG5hbWUpXG4gICAgfVxuICAgIHJldHVybiBuYW1lc1xufVxuXG4vLyBUT0RPOiBhY2Nlc3MgY29udHJvbCBvbiByZWxhdGlvbnNcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtb2RpZnlSZWxhdGlvbihjdHgsIGJvb2tzaGVsZiwgaW5zdGFuY2UsIG1vZGVsLCByZWxhdGlvbk5hbWUsIHBheWxvYWQsIHRyYW5zYWN0aW5nLCBhbGxPcHRzKSB7XG4gICAgbGV0IHJlbGF0aW9uID0gaW5zdGFuY2VbcmVsYXRpb25OYW1lXSgpO1xuICAgIGxldCByZWxhdGVkRGF0YSA9IHJlbGF0aW9uLnJlbGF0ZWREYXRhO1xuICAgIGxldCByZWxhdGlvblR5cGUgPSByZWxhdGVkRGF0YS50eXBlO1xuICAgIGxldCBmb3JlaWduS2V5ID0gcmVsYXRlZERhdGEuZm9yZWlnbktleTtcbiAgICBsZXQgdGFyZ2V0SWRBdHRyaWJ1dGUgPSByZWxhdGVkRGF0YS50YXJnZXRJZEF0dHJpYnV0ZTtcbiAgICBsZXQgdGFyZ2V0TW9kZWwgPSByZWxhdGVkRGF0YS50YXJnZXQ7XG4gICAgbGV0IHBhcmVudElkQXR0cmlidXRlID0gaW5zdGFuY2UuZ2V0KGluc3RhbmNlLmlkQXR0cmlidXRlKVxuICAgIGxldCByZWxhdGlvbk9wdHMgPSBudWxsO1xuICAgIGZvciAodmFyIGtleSBpbiBhbGxPcHRzKSB7XG4gICAgICAgIGlmIChhbGxPcHRzW2tleV0ubW9kZWwgPT0gdGFyZ2V0TW9kZWwpIHtcbiAgICAgICAgICAgIHJlbGF0aW9uT3B0cyA9IGFsbE9wdHNba2V5XVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocmVsYXRpb25UeXBlID09PSAnaGFzT25lJyB8fCByZWxhdGlvblR5cGUgPT09ICdtb3JwaE9uZScpIHtcbiAgICAgICAgaWYgKGlzTnVtYmVyKHBheWxvYWQpKSB7XG4gICAgICAgICAgICBsZXQgcmVsSW5zdGFuY2UgPSBhd2FpdCB0YXJnZXRNb2RlbC53aGVyZSh7XG4gICAgICAgICAgICAgICAgW3RhcmdldElkQXR0cmlidXRlXTogcGF5bG9hZFxuICAgICAgICAgICAgfSkuc2F2ZSh7XG4gICAgICAgICAgICAgICAgW2ZvcmVpZ25LZXldOiBwYXJlbnRJZEF0dHJpYnV0ZVxuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgIHRyYW5zYWN0aW5nOiB0cmFuc2FjdGluZyxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICd1cGRhdGUnLFxuICAgICAgICAgICAgICAgIHBhdGNoOiB0cnVlLFxuICAgICAgICAgICAgICAgIHJlcXVpcmU6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHJlbGF0aW9uIG1vZGlmaWNhdGlvbiBpcyBvbiB0YXJnZXQgbW9kZWwsXG4gICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHVzZXIgaGFzIHRhcmdldCBtb2RlbCB1cGRhdGUgcGVybWlzc2lvblxuICAgICAgICAgICAgbGV0IGNoZWNrZWQgPSBhd2FpdCBjaGVjayhjdHgsIHJlbGF0aW9uT3B0cy5pZGVudGl0eS5VLCByZWxhdGlvbk9wdHMuYWRtaW4uVSwgcmVsSW5zdGFuY2UsIHJlbGF0aW9uT3B0cy5hY2Nlc3MuVSk7XG4gICAgICAgICAgICBpZiAoIWNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcnMuRXJyT3BlcmF0aW9uTm90QXV0aG9yaXplZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHBheWxvYWQpKSB7XG4gICAgICAgICAgICBwYXlsb2FkW2ZvcmVpZ25LZXldID0gcGFyZW50SWRBdHRyaWJ1dGU7XG4gICAgICAgICAgICBsZXQgcmVsSW5zdGFuY2UgPSBhd2FpdCB0YXJnZXRNb2RlbC5mb3JnZShwYXlsb2FkKS5zYXZlKG51bGwsIHtcbiAgICAgICAgICAgICAgICB0cmFuc2FjdGluZzogdHJhbnNhY3RpbmcsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnaW5zZXJ0J1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyByZWxhdGlvbiBtb2RpZmljYXRpb24gaXMgb24gdGFyZ2V0IG1vZGVsLFxuICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB1c2VyIGhhcyB0YXJnZXQgbW9kZWwgY3JlYXRpb24gcGVybWlzc2lvblxuICAgICAgICAgICAgbGV0IGNoZWNrZWQgPSBhd2FpdCBjaGVjayhjdHgsIHJlbGF0aW9uT3B0cy5pZGVudGl0eS5DLCByZWxhdGlvbk9wdHMuYWRtaW4uQywgcmVsSW5zdGFuY2UsIHJlbGF0aW9uT3B0cy5hY2Nlc3MuQyk7XG4gICAgICAgICAgICBpZiAoIWNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcnMuRXJyT3BlcmF0aW9uTm90QXV0aG9yaXplZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycm9ycy5GbkVyclZhbHVlU2hvdWxkQmVOdW1iZXJPck9iamVjdChyZWxhdGlvbk5hbWUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChyZWxhdGlvblR5cGUgPT09ICdiZWxvbmdzVG8nIHx8IHJlbGF0aW9uVHlwZSA9PT0gJ21vcnBoVG8nKSB7XG4gICAgICAgIGxldCBmb3JlaWduQXR0cmlidXRlID0gbnVsbDtcbiAgICAgICAgaWYgKGlzTnVtYmVyKHBheWxvYWQpKSB7XG4gICAgICAgICAgICBmb3JlaWduQXR0cmlidXRlID0gcGF5bG9hZDtcbiAgICAgICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHBheWxvYWQpKSB7XG4gICAgICAgICAgICBsZXQgZm9yZWlnbkluc3RhbmNlID0gYXdhaXQgdGFyZ2V0TW9kZWwuZm9yZ2UocGF5bG9hZCkuc2F2ZShudWxsLCB7XG4gICAgICAgICAgICAgICAgdHJhbnNhY3Rpbmc6IHRyYW5zYWN0aW5nLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ2luc2VydCcsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLy8gZ2l2ZW4gcGxhaW4gb2JqZWN0LCB1c2VyIGludGVuZCB0byBjcmVhdGUgYSBmb3JlaWduIG1vZGVsIGluc3RhbmNlLFxuICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB1c2VyIGhhcyB0YXJnZXQgbW9kZWwgdXBkYXRlIHBlcm1pc3Npb25cbiAgICAgICAgICAgIGxldCBjaGVja2VkID0gYXdhaXQgY2hlY2soY3R4LCByZWxhdGlvbk9wdHMuaWRlbnRpdHkuQywgcmVsYXRpb25PcHRzLmFkbWluLkMsIGZvcmVpZ25JbnN0YW5jZSwgcmVsYXRpb25PcHRzLmFjY2Vzcy5DKTtcbiAgICAgICAgICAgIGlmICghY2hlY2tlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9ycy5FcnJPcGVyYXRpb25Ob3RBdXRob3JpemVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yZWlnbkF0dHJpYnV0ZSA9IGZvcmVpZ25JbnN0YW5jZS5nZXQoZm9yZWlnbkluc3RhbmNlLmlkQXR0cmlidXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycm9ycy5GbkVyclZhbHVlU2hvdWxkQmVOdW1iZXJPck9iamVjdChyZWxhdGlvbk5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGEgYmVsb25nc1RvIHJlbGF0aW9uIGZpZWxkIGlzIG9uIGN1cnJlbnQgaW5zdGFuY2UsIG5vIG5lZWQgdG8gY2hlY2sgYWdhaW5cbiAgICAgICAgYXdhaXQgaW5zdGFuY2Uuc2F2ZSh7XG4gICAgICAgICAgICBbZm9yZWlnbktleV06IGZvcmVpZ25BdHRyaWJ1dGVcbiAgICAgICAgfSwge1xuICAgICAgICAgICAgdHJhbnNhY3Rpbmc6IHRyYW5zYWN0aW5nLFxuICAgI