@kazekyo/nau-graphql-codegen-preset
Version:
A GraphQL Code Generator preset for Nau
234 lines (233 loc) • 34.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.PaginationVisitor = void 0;
var _visitorPluginCommon = require("@graphql-codegen/visitor-plugin-common");
var _nau = require("@kazekyo/nau");
var _autoBind = _interopRequireDefault(require("auto-bind"));
var _graphql = require("graphql");
var _graphqlSchema = require("../../utils/graphqlSchema");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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 _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var PaginationVisitor = /*#__PURE__*/function (_ClientSideBaseVisito) {
_inherits(PaginationVisitor, _ClientSideBaseVisito);
var _super = _createSuper(PaginationVisitor);
function PaginationVisitor(schema, fragments, rawConfig, documents, typeInfo) {
var _this;
_classCallCheck(this, PaginationVisitor);
_this = _super.call(this, schema, fragments, rawConfig, {});
_defineProperty(_assertThisInitialized(_this), "_typeInfo", void 0);
_defineProperty(_assertThisInitialized(_this), "_paginationMetaList", void 0);
_defineProperty(_assertThisInitialized(_this), "_deleteRecordMetaList", void 0);
_this._typeInfo = typeInfo;
_this._documents = documents;
_this._paginationMetaList = [];
_this._deleteRecordMetaList = [];
(0, _autoBind["default"])(_assertThisInitialized(_this));
return _this;
}
_createClass(PaginationVisitor, [{
key: "getImports",
value: function getImports() {
return ["import { TypePolicy } from '@apollo/client';", "import { withCacheUpdaterInternal } from '@kazekyo/nau';"];
}
}, {
key: "getContent",
value: function getContent() {
return [this.getPaginationMetaListContent(), this.getDeleteRecordMetaListContent(), this.getWithCacheUpdaterContent()].join('\n');
}
}, {
key: "getWithCacheUpdaterContent",
value: function getWithCacheUpdaterContent() {
var parentTypenames = this._paginationMetaList.map(function (meta) {
return meta.parents;
}).flat().map(function (parent) {
return parent.typename;
});
var str = "\nexport type CacheUpdaterTypePolicies = {\n ".concat(parentTypenames.map(function (typename) {
return "".concat(typename, ": TypePolicy;");
}).join('\n '), "\n [__typename: string]: TypePolicy;\n};\n\nexport const withCacheUpdater = (typePolicies: CacheUpdaterTypePolicies) =>\n withCacheUpdaterInternal({\n paginationMetaList,\n deleteRecordMetaList,\n typePolicies,\n });");
return str;
}
}, {
key: "getPaginationMetaListContent",
value: function getPaginationMetaListContent() {
return '\n' + "export const paginationMetaList = ".concat(this.printMetaListTypeScriptCode(this._paginationMetaList), ";");
}
}, {
key: "getDeleteRecordMetaListContent",
value: function getDeleteRecordMetaListContent() {
return '\n' + "export const deleteRecordMetaList = ".concat(this.printMetaListTypeScriptCode(this._deleteRecordMetaList), ";");
}
}, {
key: "printMetaListTypeScriptCode",
value: function printMetaListTypeScriptCode(object) {
var _this2 = this;
if (typeof object === 'string') {
return "'".concat(object, "'");
} else if (Array.isArray(object)) {
return "[".concat(object.map(function (v) {
return _this2.printMetaListTypeScriptCode(v);
}).join(', '), "]");
} else {
var metaObject = object;
var list = Object.entries(metaObject).map(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
k = _ref2[0],
v = _ref2[1];
return "".concat(k, ": ").concat(_this2.printMetaListTypeScriptCode(v));
});
return "{ ".concat(list.join(', '), " }");
}
}
}, {
key: "Directive",
value: function Directive(directiveNode) {
if (directiveNode.name.value !== _nau.DELETE_RECORD_DIRECTIVE_NAME) return;
}
}, {
key: "Field",
value: function Field(fieldNode) {
var paginationMeta = this.findPaginationMeta(fieldNode);
if (paginationMeta) {
this.addPaginationMetaToList(paginationMeta);
}
var deleteRecordMeta = this.findDeleteRecordMeta(fieldNode);
if (deleteRecordMeta) {
this.addDeleateRecordMetaToList(deleteRecordMeta);
}
}
}, {
key: "findDeleteRecordMeta",
value: function findDeleteRecordMeta(fieldNode) {
if (!fieldNode.directives) return;
var deleteRecordDirective = fieldNode.directives.find(function (directive) {
return directive.name.value === _nau.DELETE_RECORD_DIRECTIVE_NAME;
});
if (!deleteRecordDirective || !deleteRecordDirective.arguments) return;
var parentType = this._typeInfo.getParentType();
if (!parentType) return;
var argument = deleteRecordDirective.arguments[0];
if (argument.value.kind !== _graphql.Kind.STRING) return;
var typename = argument.value.value;
return {
parent: {
typename: parentType.toString()
},
fields: [{
fieldName: fieldNode.name.value,
typename: typename
}]
};
}
}, {
key: "addDeleateRecordMetaToList",
value: function addDeleateRecordMetaToList(deleteRecordMeta) {
var indexInMetaList = this._deleteRecordMetaList.findIndex(function (meta) {
return meta.parent.typename === deleteRecordMeta.parent.typename;
});
if (indexInMetaList === -1) {
this._deleteRecordMetaList.push(deleteRecordMeta);
return;
}
var newField = deleteRecordMeta.fields[0];
var existingMetaObject = this._deleteRecordMetaList[indexInMetaList];
var existingField = existingMetaObject.fields.find(function (field) {
return field.fieldName === newField.fieldName && field.typename === newField.typename;
});
if (existingField) return;
this._deleteRecordMetaList[indexInMetaList] = _objectSpread(_objectSpread({}, existingMetaObject), {}, {
fields: [].concat(_toConsumableArray(existingMetaObject.fields), [newField])
});
}
}, {
key: "findPaginationMeta",
value: function findPaginationMeta(fieldNode) {
if (!fieldNode.directives) return;
var paginationDirective = fieldNode.directives.find(function (directive) {
return directive.name.value === _nau.PAGINATION_DIRECTIVE_NAME;
});
if (!paginationDirective) return;
var connectionType = (0, _graphqlSchema.getConnectionType)({
type: this._typeInfo.getType()
});
if (!connectionType) return;
var edgeType = (0, _graphqlSchema.getEdgeType)({
connectionType: connectionType,
schema: this._schema
});
if (!edgeType) return;
var nodeType = (0, _graphqlSchema.getNodeType)({
edgeType: edgeType,
schema: this._schema
});
if (!nodeType) return;
var parentType = this._typeInfo.getParentType();
if (!parentType) return;
var newParentMeta = {
typename: parentType.toString(),
connection: {
fieldName: fieldNode.name.value
},
edge: {
typename: edgeType.toString()
}
};
return {
node: {
typename: nodeType.toString()
},
parents: [newParentMeta]
};
}
}, {
key: "addPaginationMetaToList",
value: function addPaginationMetaToList(paginationMeta) {
var nodeIndexInMetaList = this._paginationMetaList.findIndex(function (meta) {
return meta.node.typename === paginationMeta.node.typename;
});
if (nodeIndexInMetaList === -1) {
this._paginationMetaList.push(paginationMeta);
return;
}
var newParent = paginationMeta.parents[0];
var existingMetaObject = this._paginationMetaList[nodeIndexInMetaList];
var existingParent = existingMetaObject.parents.find(function (parent) {
return parent.typename === newParent.typename && parent.connection.fieldName === newParent.connection.fieldName && parent.edge.typename === newParent.edge.typename;
});
if (existingParent) return;
this._paginationMetaList[nodeIndexInMetaList] = _objectSpread(_objectSpread({}, existingMetaObject), {}, {
parents: [].concat(_toConsumableArray(existingMetaObject.parents), [newParent])
});
}
}]);
return PaginationVisitor;
}(_visitorPluginCommon.ClientSideBaseVisitor);
exports.PaginationVisitor = PaginationVisitor;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYWdpbmF0aW9uVmlzaXRvciIsInNjaGVtYSIsImZyYWdtZW50cyIsInJhd0NvbmZpZyIsImRvY3VtZW50cyIsInR5cGVJbmZvIiwiX3R5cGVJbmZvIiwiX2RvY3VtZW50cyIsIl9wYWdpbmF0aW9uTWV0YUxpc3QiLCJfZGVsZXRlUmVjb3JkTWV0YUxpc3QiLCJhdXRvQmluZCIsImdldFBhZ2luYXRpb25NZXRhTGlzdENvbnRlbnQiLCJnZXREZWxldGVSZWNvcmRNZXRhTGlzdENvbnRlbnQiLCJnZXRXaXRoQ2FjaGVVcGRhdGVyQ29udGVudCIsImpvaW4iLCJwYXJlbnRUeXBlbmFtZXMiLCJtYXAiLCJtZXRhIiwicGFyZW50cyIsImZsYXQiLCJwYXJlbnQiLCJ0eXBlbmFtZSIsInN0ciIsInByaW50TWV0YUxpc3RUeXBlU2NyaXB0Q29kZSIsIm9iamVjdCIsIkFycmF5IiwiaXNBcnJheSIsInYiLCJtZXRhT2JqZWN0IiwibGlzdCIsIk9iamVjdCIsImVudHJpZXMiLCJrIiwiZGlyZWN0aXZlTm9kZSIsIm5hbWUiLCJ2YWx1ZSIsIkRFTEVURV9SRUNPUkRfRElSRUNUSVZFX05BTUUiLCJmaWVsZE5vZGUiLCJwYWdpbmF0aW9uTWV0YSIsImZpbmRQYWdpbmF0aW9uTWV0YSIsImFkZFBhZ2luYXRpb25NZXRhVG9MaXN0IiwiZGVsZXRlUmVjb3JkTWV0YSIsImZpbmREZWxldGVSZWNvcmRNZXRhIiwiYWRkRGVsZWF0ZVJlY29yZE1ldGFUb0xpc3QiLCJkaXJlY3RpdmVzIiwiZGVsZXRlUmVjb3JkRGlyZWN0aXZlIiwiZmluZCIsImRpcmVjdGl2ZSIsImFyZ3VtZW50cyIsInBhcmVudFR5cGUiLCJnZXRQYXJlbnRUeXBlIiwiYXJndW1lbnQiLCJraW5kIiwiS2luZCIsIlNUUklORyIsInRvU3RyaW5nIiwiZmllbGRzIiwiZmllbGROYW1lIiwiaW5kZXhJbk1ldGFMaXN0IiwiZmluZEluZGV4IiwicHVzaCIsIm5ld0ZpZWxkIiwiZXhpc3RpbmdNZXRhT2JqZWN0IiwiZXhpc3RpbmdGaWVsZCIsImZpZWxkIiwicGFnaW5hdGlvbkRpcmVjdGl2ZSIsIlBBR0lOQVRJT05fRElSRUNUSVZFX05BTUUiLCJjb25uZWN0aW9uVHlwZSIsImdldENvbm5lY3Rpb25UeXBlIiwidHlwZSIsImdldFR5cGUiLCJlZGdlVHlwZSIsImdldEVkZ2VUeXBlIiwiX3NjaGVtYSIsIm5vZGVUeXBlIiwiZ2V0Tm9kZVR5cGUiLCJuZXdQYXJlbnRNZXRhIiwiY29ubmVjdGlvbiIsImVkZ2UiLCJub2RlIiwibm9kZUluZGV4SW5NZXRhTGlzdCIsIm5ld1BhcmVudCIsImV4aXN0aW5nUGFyZW50IiwiQ2xpZW50U2lkZUJhc2VWaXNpdG9yIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3BsdWdpbnMvY2FjaGUtdXBkYXRlci1zdXBwb3J0L3Zpc2l0b3IudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVHlwZXMgfSBmcm9tICdAZ3JhcGhxbC1jb2RlZ2VuL3BsdWdpbi1oZWxwZXJzJztcbmltcG9ydCB7IENsaWVudFNpZGVCYXNlVmlzaXRvciwgTG9hZGVkRnJhZ21lbnQgfSBmcm9tICdAZ3JhcGhxbC1jb2RlZ2VuL3Zpc2l0b3ItcGx1Z2luLWNvbW1vbic7XG5pbXBvcnQge1xuICBEZWxldGVSZWNvcmRNZXRhLFxuICBERUxFVEVfUkVDT1JEX0RJUkVDVElWRV9OQU1FLFxuICBQYWdpbmF0aW9uTWV0YSxcbiAgUEFHSU5BVElPTl9ESVJFQ1RJVkVfTkFNRSxcbn0gZnJvbSAnQGthemVreW8vbmF1JztcbmltcG9ydCBhdXRvQmluZCBmcm9tICdhdXRvLWJpbmQnO1xuaW1wb3J0IHsgRGlyZWN0aXZlTm9kZSwgRmllbGROb2RlLCBHcmFwaFFMU2NoZW1hLCBLaW5kLCBUeXBlSW5mbyB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZ2V0Q29ubmVjdGlvblR5cGUsIGdldEVkZ2VUeXBlLCBnZXROb2RlVHlwZSB9IGZyb20gJy4uLy4uL3V0aWxzL2dyYXBocWxTY2hlbWEnO1xuaW1wb3J0IHsgUGFnaW5hdGlvblBsdWdpbkNvbmZpZywgUGFnaW5hdGlvblJhd1BsdWdpbkNvbmZpZyB9IGZyb20gJy4vY29uZmlnJztcblxuZXhwb3J0IGNsYXNzIFBhZ2luYXRpb25WaXNpdG9yIGV4dGVuZHMgQ2xpZW50U2lkZUJhc2VWaXNpdG9yPFBhZ2luYXRpb25SYXdQbHVnaW5Db25maWcsIFBhZ2luYXRpb25QbHVnaW5Db25maWc+IHtcbiAgcHJpdmF0ZSBfdHlwZUluZm86IFR5cGVJbmZvO1xuICBwcml2YXRlIF9wYWdpbmF0aW9uTWV0YUxpc3Q6IFBhZ2luYXRpb25NZXRhW107XG4gIHByaXZhdGUgX2RlbGV0ZVJlY29yZE1ldGFMaXN0OiBEZWxldGVSZWNvcmRNZXRhW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NoZW1hOiBHcmFwaFFMU2NoZW1hLFxuICAgIGZyYWdtZW50czogTG9hZGVkRnJhZ21lbnRbXSxcbiAgICByYXdDb25maWc6IFBhZ2luYXRpb25SYXdQbHVnaW5Db25maWcsXG4gICAgZG9jdW1lbnRzOiBUeXBlcy5Eb2N1bWVudEZpbGVbXSxcbiAgICB0eXBlSW5mbzogVHlwZUluZm8sXG4gICkge1xuICAgIHN1cGVyKHNjaGVtYSwgZnJhZ21lbnRzLCByYXdDb25maWcsIHt9KTtcblxuICAgIHRoaXMuX3R5cGVJbmZvID0gdHlwZUluZm87XG4gICAgdGhpcy5fZG9jdW1lbnRzID0gZG9jdW1lbnRzO1xuICAgIHRoaXMuX3BhZ2luYXRpb25NZXRhTGlzdCA9IFtdO1xuICAgIHRoaXMuX2RlbGV0ZVJlY29yZE1ldGFMaXN0ID0gW107XG5cbiAgICBhdXRvQmluZCh0aGlzKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRJbXBvcnRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW2BpbXBvcnQgeyBUeXBlUG9saWN5IH0gZnJvbSAnQGFwb2xsby9jbGllbnQnO2AsIGBpbXBvcnQgeyB3aXRoQ2FjaGVVcGRhdGVySW50ZXJuYWwgfSBmcm9tICdAa2F6ZWt5by9uYXUnO2BdO1xuICB9XG5cbiAgcHVibGljIGdldENvbnRlbnQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5nZXRQYWdpbmF0aW9uTWV0YUxpc3RDb250ZW50KCksXG4gICAgICB0aGlzLmdldERlbGV0ZVJlY29yZE1ldGFMaXN0Q29udGVudCgpLFxuICAgICAgdGhpcy5nZXRXaXRoQ2FjaGVVcGRhdGVyQ29udGVudCgpLFxuICAgIF0uam9pbignXFxuJyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0V2l0aENhY2hlVXBkYXRlckNvbnRlbnQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJlbnRUeXBlbmFtZXMgPSB0aGlzLl9wYWdpbmF0aW9uTWV0YUxpc3RcbiAgICAgIC5tYXAoKG1ldGEpID0+IG1ldGEucGFyZW50cylcbiAgICAgIC5mbGF0KClcbiAgICAgIC5tYXAoKHBhcmVudCkgPT4gcGFyZW50LnR5cGVuYW1lKTtcblxuICAgIGNvbnN0IHN0ciA9IGBcbmV4cG9ydCB0eXBlIENhY2hlVXBkYXRlclR5cGVQb2xpY2llcyA9IHtcbiAgJHtwYXJlbnRUeXBlbmFtZXMubWFwKCh0eXBlbmFtZSkgPT4gYCR7dHlwZW5hbWV9OiBUeXBlUG9saWN5O2ApLmpvaW4oJ1xcbiAgJyl9XG4gIFtfX3R5cGVuYW1lOiBzdHJpbmddOiBUeXBlUG9saWN5O1xufTtcblxuZXhwb3J0IGNvbnN0IHdpdGhDYWNoZVVwZGF0ZXIgPSAodHlwZVBvbGljaWVzOiBDYWNoZVVwZGF0ZXJUeXBlUG9saWNpZXMpID0+XG4gIHdpdGhDYWNoZVVwZGF0ZXJJbnRlcm5hbCh7XG4gICAgcGFnaW5hdGlvbk1ldGFMaXN0LFxuICAgIGRlbGV0ZVJlY29yZE1ldGFMaXN0LFxuICAgIHR5cGVQb2xpY2llcyxcbiAgfSk7YDtcbiAgICByZXR1cm4gc3RyO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYWdpbmF0aW9uTWV0YUxpc3RDb250ZW50KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdcXG4nICsgYGV4cG9ydCBjb25zdCBwYWdpbmF0aW9uTWV0YUxpc3QgPSAke3RoaXMucHJpbnRNZXRhTGlzdFR5cGVTY3JpcHRDb2RlKHRoaXMuX3BhZ2luYXRpb25NZXRhTGlzdCl9O2A7XG4gIH1cblxuICBwcml2YXRlIGdldERlbGV0ZVJlY29yZE1ldGFMaXN0Q29udGVudCgpOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICAnXFxuJyArIGBleHBvcnQgY29uc3QgZGVsZXRlUmVjb3JkTWV0YUxpc3QgPSAke3RoaXMucHJpbnRNZXRhTGlzdFR5cGVTY3JpcHRDb2RlKHRoaXMuX2RlbGV0ZVJlY29yZE1ldGFMaXN0KX07YFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHByaW50TWV0YUxpc3RUeXBlU2NyaXB0Q29kZShvYmplY3Q6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGAnJHtvYmplY3R9J2A7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHtcbiAgICAgIHJldHVybiBgWyR7b2JqZWN0Lm1hcCgodikgPT4gdGhpcy5wcmludE1ldGFMaXN0VHlwZVNjcmlwdENvZGUodikpLmpvaW4oJywgJyl9XWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG1ldGFPYmplY3QgPSBvYmplY3QgYXMgeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH07XG4gICAgICBjb25zdCBsaXN0ID0gT2JqZWN0LmVudHJpZXMobWV0YU9iamVjdCkubWFwKChbaywgdl0pID0+IGAke2t9OiAke3RoaXMucHJpbnRNZXRhTGlzdFR5cGVTY3JpcHRDb2RlKHYpfWApO1xuICAgICAgcmV0dXJuIGB7ICR7bGlzdC5qb2luKCcsICcpfSB9YDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgRGlyZWN0aXZlKGRpcmVjdGl2ZU5vZGU6IERpcmVjdGl2ZU5vZGUpOiB2b2lkIHtcbiAgICBpZiAoZGlyZWN0aXZlTm9kZS5uYW1lLnZhbHVlICE9PSBERUxFVEVfUkVDT1JEX0RJUkVDVElWRV9OQU1FKSByZXR1cm47XG4gIH1cblxuICBwdWJsaWMgRmllbGQoZmllbGROb2RlOiBGaWVsZE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBwYWdpbmF0aW9uTWV0YSA9IHRoaXMuZmluZFBhZ2luYXRpb25NZXRhKGZpZWxkTm9kZSk7XG4gICAgaWYgKHBhZ2luYXRpb25NZXRhKSB7XG4gICAgICB0aGlzLmFkZFBhZ2luYXRpb25NZXRhVG9MaXN0KHBhZ2luYXRpb25NZXRhKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWxldGVSZWNvcmRNZXRhID0gdGhpcy5maW5kRGVsZXRlUmVjb3JkTWV0YShmaWVsZE5vZGUpO1xuICAgIGlmIChkZWxldGVSZWNvcmRNZXRhKSB7XG4gICAgICB0aGlzLmFkZERlbGVhdGVSZWNvcmRNZXRhVG9MaXN0KGRlbGV0ZVJlY29yZE1ldGEpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmluZERlbGV0ZVJlY29yZE1ldGEoZmllbGROb2RlOiBGaWVsZE5vZGUpOiBEZWxldGVSZWNvcmRNZXRhIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWZpZWxkTm9kZS5kaXJlY3RpdmVzKSByZXR1cm47XG4gICAgY29uc3QgZGVsZXRlUmVjb3JkRGlyZWN0aXZlID0gZmllbGROb2RlLmRpcmVjdGl2ZXMuZmluZChcbiAgICAgIChkaXJlY3RpdmUpID0+IGRpcmVjdGl2ZS5uYW1lLnZhbHVlID09PSBERUxFVEVfUkVDT1JEX0RJUkVDVElWRV9OQU1FLFxuICAgICk7XG4gICAgaWYgKCFkZWxldGVSZWNvcmREaXJlY3RpdmUgfHwgIWRlbGV0ZVJlY29yZERpcmVjdGl2ZS5hcmd1bWVudHMpIHJldHVybjtcblxuICAgIGNvbnN0IHBhcmVudFR5cGUgPSB0aGlzLl90eXBlSW5mby5nZXRQYXJlbnRUeXBlKCk7XG4gICAgaWYgKCFwYXJlbnRUeXBlKSByZXR1cm47XG5cbiAgICBjb25zdCBhcmd1bWVudCA9IGRlbGV0ZVJlY29yZERpcmVjdGl2ZS5hcmd1bWVudHNbMF07XG4gICAgaWYgKGFyZ3VtZW50LnZhbHVlLmtpbmQgIT09IEtpbmQuU1RSSU5HKSByZXR1cm47XG4gICAgY29uc3QgdHlwZW5hbWUgPSBhcmd1bWVudC52YWx1ZS52YWx1ZTtcblxuICAgIHJldHVybiB7IHBhcmVudDogeyB0eXBlbmFtZTogcGFyZW50VHlwZS50b1N0cmluZygpIH0sIGZpZWxkczogW3sgZmllbGROYW1lOiBmaWVsZE5vZGUubmFtZS52YWx1ZSwgdHlwZW5hbWUgfV0gfTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRGVsZWF0ZVJlY29yZE1ldGFUb0xpc3QoZGVsZXRlUmVjb3JkTWV0YTogRGVsZXRlUmVjb3JkTWV0YSk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4SW5NZXRhTGlzdCA9IHRoaXMuX2RlbGV0ZVJlY29yZE1ldGFMaXN0LmZpbmRJbmRleChcbiAgICAgIChtZXRhKSA9PiBtZXRhLnBhcmVudC50eXBlbmFtZSA9PT0gZGVsZXRlUmVjb3JkTWV0YS5wYXJlbnQudHlwZW5hbWUsXG4gICAgKTtcbiAgICBpZiAoaW5kZXhJbk1ldGFMaXN0ID09PSAtMSkge1xuICAgICAgdGhpcy5fZGVsZXRlUmVjb3JkTWV0YUxpc3QucHVzaChkZWxldGVSZWNvcmRNZXRhKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdGaWVsZCA9IGRlbGV0ZVJlY29yZE1ldGEuZmllbGRzWzBdO1xuXG4gICAgY29uc3QgZXhpc3RpbmdNZXRhT2JqZWN0ID0gdGhpcy5fZGVsZXRlUmVjb3JkTWV0YUxpc3RbaW5kZXhJbk1ldGFMaXN0XTtcbiAgICBjb25zdCBleGlzdGluZ0ZpZWxkID0gZXhpc3RpbmdNZXRhT2JqZWN0LmZpZWxkcy5maW5kKFxuICAgICAgKGZpZWxkKSA9PiBmaWVsZC5maWVsZE5hbWUgPT09IG5ld0ZpZWxkLmZpZWxkTmFtZSAmJiBmaWVsZC50eXBlbmFtZSA9PT0gbmV3RmllbGQudHlwZW5hbWUsXG4gICAgKTtcbiAgICBpZiAoZXhpc3RpbmdGaWVsZCkgcmV0dXJuO1xuXG4gICAgdGhpcy5fZGVsZXRlUmVjb3JkTWV0YUxpc3RbaW5kZXhJbk1ldGFMaXN0XSA9IHtcbiAgICAgIC4uLmV4aXN0aW5nTWV0YU9iamVjdCxcbiAgICAgIGZpZWxkczogWy4uLmV4aXN0aW5nTWV0YU9iamVjdC5maWVsZHMsIG5ld0ZpZWxkXSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kUGFnaW5hdGlvbk1ldGEoZmllbGROb2RlOiBGaWVsZE5vZGUpOiBQYWdpbmF0aW9uTWV0YSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFmaWVsZE5vZGUuZGlyZWN0aXZlcykgcmV0dXJuO1xuICAgIGNvbnN0IHBhZ2luYXRpb25EaXJlY3RpdmUgPSBmaWVsZE5vZGUuZGlyZWN0aXZlcy5maW5kKFxuICAgICAgKGRpcmVjdGl2ZSkgPT4gZGlyZWN0aXZlLm5hbWUudmFsdWUgPT09IFBBR0lOQVRJT05fRElSRUNUSVZFX05BTUUsXG4gICAgKTtcbiAgICBpZiAoIXBhZ2luYXRpb25EaXJlY3RpdmUpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbm5lY3Rpb25UeXBlID0gZ2V0Q29ubmVjdGlvblR5cGUoeyB0eXBlOiB0aGlzLl90eXBlSW5mby5nZXRUeXBlKCkgfSk7XG4gICAgaWYgKCFjb25uZWN0aW9uVHlwZSkgcmV0dXJuO1xuXG4gICAgY29uc3QgZWRnZVR5cGUgPSBnZXRFZGdlVHlwZSh7IGNvbm5lY3Rpb25UeXBlLCBzY2hlbWE6IHRoaXMuX3NjaGVtYSB9KTtcbiAgICBpZiAoIWVkZ2VUeXBlKSByZXR1cm47XG5cbiAgICBjb25zdCBub2RlVHlwZSA9IGdldE5vZGVUeXBlKHsgZWRnZVR5cGUsIHNjaGVtYTogdGhpcy5fc2NoZW1hIH0pO1xuICAgIGlmICghbm9kZVR5cGUpIHJldHVybjtcblxuICAgIGNvbnN0IHBhcmVudFR5cGUgPSB0aGlzLl90eXBlSW5mby5nZXRQYXJlbnRUeXBlKCk7XG4gICAgaWYgKCFwYXJlbnRUeXBlKSByZXR1cm47XG5cbiAgICBjb25zdCBuZXdQYXJlbnRNZXRhOiBQYWdpbmF0aW9uTWV0YVsncGFyZW50cyddWycwJ10gPSB7XG4gICAgICB0eXBlbmFtZTogcGFyZW50VHlwZS50b1N0cmluZygpLFxuICAgICAgY29ubmVjdGlvbjogeyBmaWVsZE5hbWU6IGZpZWxkTm9kZS5uYW1lLnZhbHVlIH0sXG4gICAgICBlZGdlOiB7IHR5cGVuYW1lOiBlZGdlVHlwZS50b1N0cmluZygpIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBub2RlOiB7IHR5cGVuYW1lOiBub2RlVHlwZS50b1N0cmluZygpIH0sXG4gICAgICBwYXJlbnRzOiBbbmV3UGFyZW50TWV0YV0sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUGFnaW5hdGlvbk1ldGFUb0xpc3QocGFnaW5hdGlvbk1ldGE6IFBhZ2luYXRpb25NZXRhKTogdm9pZCB7XG4gICAgY29uc3Qgbm9kZUluZGV4SW5NZXRhTGlzdCA9IHRoaXMuX3BhZ2luYXRpb25NZXRhTGlzdC5maW5kSW5kZXgoXG4gICAgICAobWV0YSkgPT4gbWV0YS5ub2RlLnR5cGVuYW1lID09PSBwYWdpbmF0aW9uTWV0YS5ub2RlLnR5cGVuYW1lLFxuICAgICk7XG4gICAgaWYgKG5vZGVJbmRleEluTWV0YUxpc3QgPT09IC0xKSB7XG4gICAgICB0aGlzLl9wYWdpbmF0aW9uTWV0YUxpc3QucHVzaChwYWdpbmF0aW9uTWV0YSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbmV3UGFyZW50ID0gcGFnaW5hdGlvbk1ldGEucGFyZW50c1swXTtcblxuICAgIGNvbnN0IGV4aXN0aW5nTWV0YU9iamVjdCA9IHRoaXMuX3BhZ2luYXRpb25NZXRhTGlzdFtub2RlSW5kZXhJbk1ldGFMaXN0XTtcbiAgICBjb25zdCBleGlzdGluZ1BhcmVudCA9IGV4aXN0aW5nTWV0YU9iamVjdC5wYXJlbnRzLmZpbmQoXG4gICAgICAocGFyZW50KSA9PlxuICAgICAgICBwYXJlbnQudHlwZW5hbWUgPT09IG5ld1BhcmVudC50eXBlbmFtZSAmJlxuICAgICAgICBwYXJlbnQuY29ubmVjdGlvbi5maWVsZE5hbWUgPT09IG5ld1BhcmVudC5jb25uZWN0aW9uLmZpZWxkTmFtZSAmJlxuICAgICAgICBwYXJlbnQuZWRnZS50eXBlbmFtZSA9PT0gbmV3UGFyZW50LmVkZ2UudHlwZW5hbWUsXG4gICAgKTtcbiAgICBpZiAoZXhpc3RpbmdQYXJlbnQpIHJldHVybjtcblxuICAgIHRoaXMuX3BhZ2luYXRpb25NZXRhTGlzdFtub2RlSW5kZXhJbk1ldGFMaXN0XSA9IHtcbiAgICAgIC4uLmV4aXN0aW5nTWV0YU9iamVjdCxcbiAgICAgIHBhcmVudHM6IFsuLi5leGlzdGluZ01ldGFPYmplY3QucGFyZW50cywgbmV3UGFyZW50XSxcbiAgICB9O1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFBd0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsSUFHM0VBLGlCQUFpQjtFQUFBO0VBQUE7RUFLNUIsMkJBQ0VDLE1BQXFCLEVBQ3JCQyxTQUEyQixFQUMzQkMsU0FBb0MsRUFDcENDLFNBQStCLEVBQy9CQyxRQUFrQixFQUNsQjtJQUFBO0lBQUE7SUFDQSwwQkFBTUosTUFBTSxFQUFFQyxTQUFTLEVBQUVDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFBRTtJQUFBO0lBQUE7SUFFeEMsTUFBS0csU0FBUyxHQUFHRCxRQUFRO0lBQ3pCLE1BQUtFLFVBQVUsR0FBR0gsU0FBUztJQUMzQixNQUFLSSxtQkFBbUIsR0FBRyxFQUFFO0lBQzdCLE1BQUtDLHFCQUFxQixHQUFHLEVBQUU7SUFFL0IsSUFBQUMsb0JBQVEsZ0NBQU07SUFBQztFQUNqQjtFQUFDO0lBQUE7SUFBQSxPQUVELHNCQUE4QjtNQUM1QixPQUFPLDRHQUE0RztJ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