UNPKG

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
'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