UNPKG

@kazekyo/nau-graphql-codegen-preset

Version:

A GraphQL Code Generator preset for Nau

234 lines (233 loc) 34.3 kB
"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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