UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

182 lines 27.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAllPropertyDecoratorsRecursive = exports.getHandlerArgs = void 0; exports.enforceDBDecorators = enforceDBDecorators; exports.getDbDecorators = getDbDecorators; const Operations_1 = require("./../operations/Operations.cjs"); const constants_1 = require("./../operations/constants.cjs"); const reflection_1 = require("@decaf-ts/reflection"); const errors_1 = require("./errors.cjs"); const decorator_validation_1 = require("@decaf-ts/decorator-validation"); /** * @summary retrieves the arguments for the handler * @param {any} dec the decorator * @param {string} prop the property name * @param {{}} m the model * @param {{}} [accum] accumulator used for internal recursiveness * * @function getHandlerArgs * @memberOf module:db-decorators.Repository */ const getHandlerArgs = function (dec, prop, m, accum) { const name = m.constructor.name; if (!name) throw new errors_1.InternalError("Could not determine model class"); accum = accum || {}; if (dec.props.handlers[name] && dec.props.handlers[name][prop]) accum = { ...dec.props.handlers[name][prop], ...accum }; let proto = Object.getPrototypeOf(m); if (proto === Object.prototype) return accum; if (proto.constructor.name === name) proto = Object.getPrototypeOf(proto); return (0, exports.getHandlerArgs)(dec, prop, proto, accum); }; exports.getHandlerArgs = getHandlerArgs; /** * * @param {IRepository<T>} repo * @param context * @param {T} model * @param operation * @param prefix * * @param oldModel * @function enforceDBPropertyDecoratorsAsync * * @memberOf db-decorators.utils */ async function enforceDBDecorators(repo, context, model, operation, prefix, oldModel) { const decorators = getDbDecorators(model, operation, prefix); if (!decorators) return; for (const prop in decorators) { const decs = decorators[prop]; for (const dec of decs) { const { key } = dec; const handlers = Operations_1.Operations.get(model, prop, prefix + key); if (!handlers || !handlers.length) throw new errors_1.InternalError(`Could not find registered handler for the operation ${prefix + key} under property ${prop}`); const handlerArgs = (0, exports.getHandlerArgs)(dec, prop, model); if (!handlerArgs || Object.values(handlerArgs).length !== handlers.length) throw new errors_1.InternalError("Args and handlers length do not match"); let handler; let data; for (let i = 0; i < handlers.length; i++) { handler = handlers[i]; data = Object.values(handlerArgs)[i]; const args = [context, data.data, prop, model]; if (operation === constants_1.OperationKeys.UPDATE && prefix === constants_1.OperationKeys.ON) { if (!oldModel) throw new errors_1.InternalError("Missing old model for update operation"); args.push(oldModel); } try { await handler.apply(repo, args); } catch (e) { const msg = `Failed to execute handler ${handler.name} for ${prop} on ${model.constructor.name} due to error: ${e}`; if (context.get("breakOnHandlerError")) throw new errors_1.InternalError(msg); console.log(msg); } } } } } /** * Specific for DB Decorators * @param {T} model * @param {string} operation CRUD {@link OperationKeys} * @param {string} [extraPrefix] * * @function getDbPropertyDecorators * * @memberOf db-decorators.utils */ function getDbDecorators(model, operation, extraPrefix) { const decorators = reflection_1.Reflection.getAllPropertyDecorators(model, // undefined, constants_1.OperationKeys.REFLECT + (extraPrefix ? extraPrefix : "")); if (!decorators) return; return Object.keys(decorators).reduce((accum, decorator) => { const dec = decorators[decorator].filter((d) => d.key === operation); if (dec && dec.length) { if (!accum) accum = {}; accum[decorator] = dec; } return accum; }, undefined); } /** * @summary Retrieves the decorators for an object's properties prefixed by {@param prefixes} recursively * @param model * @param accum * @param prefixes * * @function getAllPropertyDecoratorsRecursive * @memberOf module:db-decorators.Repository */ const getAllPropertyDecoratorsRecursive = function (model, accum, ...prefixes) { const accumulator = accum || {}; const mergeDecorators = function (decs) { const pushOrSquash = (key, ...values) => { values.forEach((val) => { let match; if (!(match = accumulator[key].find((e) => e.key === val.key)) || match.props.operation !== val.props.operation) { accumulator[key].push(val); return; } if (val.key === decorator_validation_1.ModelKeys.TYPE) return; const { handlers, operation } = val.props; if (!operation || !operation.match(new RegExp(`^(:?${constants_1.OperationKeys.ON}|${constants_1.OperationKeys.AFTER})(:?${constants_1.OperationKeys.CREATE}|${constants_1.OperationKeys.READ}|${constants_1.OperationKeys.UPDATE}|${constants_1.OperationKeys.DELETE})$`))) { accumulator[key].push(val); return; } const accumHandlers = match.props.handlers; Object.entries(handlers).forEach(([clazz, handlerDef]) => { if (!(clazz in accumHandlers)) { accumHandlers[clazz] = handlerDef; return; } Object.entries(handlerDef).forEach(([handlerProp, handler]) => { if (!(handlerProp in accumHandlers[clazz])) { accumHandlers[clazz][handlerProp] = handler; return; } Object.entries(handler).forEach(([handlerKey, argsObj]) => { if (!(handlerKey in accumHandlers[clazz][handlerProp])) { accumHandlers[clazz][handlerProp][handlerKey] = argsObj; return; } console.warn(`Skipping handler registration for ${clazz} under prop ${handlerProp} because handler is the same`); }); }); }); }); }; Object.entries(decs).forEach(([key, value]) => { accumulator[key] = accumulator[key] || []; pushOrSquash(key, ...value); }); }; const decs = reflection_1.Reflection.getAllPropertyDecorators(model, ...prefixes); if (decs) mergeDecorators(decs); if (Object.getPrototypeOf(model) === Object.prototype) return accumulator; // const name = model.constructor.name; const proto = Object.getPrototypeOf(model); if (!proto) return accumulator; // if (proto.constructor && proto.constructor.name === name) // proto = Object.getPrototypeOf(proto) return (0, exports.getAllPropertyDecoratorsRecursive)(proto, accumulator, ...prefixes); }; exports.getAllPropertyDecoratorsRecursive = getAllPropertyDecoratorsRecursive; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVwb3NpdG9yeS91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUF3RUEsa0RBNkRDO0FBWUQsMENBdUJDO0FBeEtELCtEQUFzRDtBQUd0RCw2REFBd0Q7QUFDeEQscURBQXFFO0FBQ3JFLHlDQUF5QztBQUN6Qyx5RUFBK0U7QUF1Qi9FOzs7Ozs7Ozs7R0FTRztBQUNJLE1BQU0sY0FBYyxHQUFHLFVBQzVCLEdBQVEsRUFDUixJQUFZLEVBQ1osQ0FBbUIsRUFDbkIsS0FBMEM7SUFFMUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7SUFDaEMsSUFBSSxDQUFDLElBQUk7UUFBRSxNQUFNLElBQUksc0JBQWEsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ3RFLEtBQUssR0FBRyxLQUFLLElBQUksRUFBRSxDQUFDO0lBRXBCLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzVELEtBQUssR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsQ0FBQztJQUUxRCxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLElBQUksS0FBSyxLQUFLLE1BQU0sQ0FBQyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksS0FBSyxJQUFJO1FBQUUsS0FBSyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFMUUsT0FBTyxJQUFBLHNCQUFjLEVBQUMsR0FBRyxF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QUFJLEVBQUUsQ0FBQztZQUMxQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUM7SUFFRixNQUFNLElBQUksR0FDUix1QkFBVSxDQUFDLHdCQUF3QixDQUFDLEtBQUssRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDO0lBQzFELElBQUksSUFBSTtRQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVoQyxJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEtBQUssTUFBTSxDQUFDLFNBQVM7UUFBRSxPQUFPLFdBQVcsQ0FBQztJQUUxRSx1Q0FBdUM7SUFDdkMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sV0FBVyxDQUFDO0lBQy9CLDREQUE0RDtJQUM1RCwyQ0FBMkM7SUFDM0MsT0FBTyxJQUFBLHlDQUFpQyxFQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQztBQUM1RSxDQUFDLENBQUM7QUFwRlcsUUFBQSxpQ0FBaUMscUNBb0Y1QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9wZXJhdGlvbnMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9PcGVyYXRpb25zXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25IYW5kbGVyLCBVcGRhdGVPcGVyYXRpb25IYW5kbGVyIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvdHlwZXNcIjtcbmltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9jb25zdGFudHNcIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwsIE1vZGVsS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb250ZXh0IGFyZ3VtZW50cyBmb3IgcmVwb3NpdG9yeSBvcGVyYXRpb25zLlxuICogQHN1bW1hcnkgUmVwcmVzZW50cyB0aGUgY29udGV4dCBhbmQgYXJndW1lbnRzIGZvciByZXBvc2l0b3J5IG9wZXJhdGlvbnMuXG4gKiBUaGlzIHR5cGUgaXMgdXNlZCB0byBwYXNzIGNvbnRleHQgYW5kIGFyZ3VtZW50cyBiZXR3ZWVuIHJlcG9zaXRvcnkgbWV0aG9kcy5cbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZSwgZGVmYXVsdHMgdG8gUmVwb3NpdG9yeUZsYWdzXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUsIGRlZmF1bHRzIHRvIENvbnRleHQ8Rj5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IENvbnRleHRBcmdzXG4gKiBAcHJvcGVydHkge0N9IGNvbnRleHQgLSBUaGUgb3BlcmF0aW9uIGNvbnRleHRcbiAqIEBwcm9wZXJ0eSB7YW55W119IGFyZ3MgLSBUaGUgb3BlcmF0aW9uIGFyZ3VtZW50c1xuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCB0eXBlIENvbnRleHRBcmdzPFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+ID0ge1xuICBjb250ZXh0OiBDO1xuICBhcmdzOiBhbnlbXTtcbn07XG5cbi8qKlxuICogQHN1bW1hcnkgcmV0cmlldmVzIHRoZSBhcmd1bWVudHMgZm9yIHRoZSBoYW5kbGVyXG4gKiBAcGFyYW0ge2FueX0gZGVjIHRoZSBkZWNvcmF0b3JcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIHRoZSBwcm9wZXJ0eSBuYW1lXG4gKiBAcGFyYW0ge3t9fSBtIHRoZSBtb2RlbFxuICogQHBhcmFtIHt7fX0gW2FjY3VtXSBhY2N1bXVsYXRvciB1c2VkIGZvciBpbnRlcm5hbCByZWN1cnNpdmVuZXNzXG4gKlxuICogQGZ1bmN0aW9uIGdldEhhbmRsZXJBcmdzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuUmVwb3NpdG9yeVxuICovXG5leHBvcnQgY29uc3QgZ2V0SGFuZGxlckFyZ3MgPSBmdW5jdGlvbiAoXG4gIGRlYzogYW55LFxuICBwcm9wOiBzdHJpbmcsXG4gIG06IENvbnN0cnVjdG9yPGFueT4sXG4gIGFjY3VtPzogUmVjb3JkPHN0cmluZywgeyBhcmdzOiBzdHJpbmdbXSB9PlxuKTogUmVjb3JkPHN0cmluZywgeyBhcmdzOiBzdHJpbmdbXSB9PiB8IHZvaWQge1xuICBjb25zdCBuYW1lID0gbS5jb25zdHJ1Y3Rvci5uYW1lO1xuICBpZiAoIW5hbWUpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiQ291bGQgbm90IGRldGVybWluZSBtb2RlbCBjbGFzc1wiKTtcbiAgYWNjdW0gPSBhY2N1bSB8fCB7fTtcblxuICBpZiAoZGVjLnByb3BzLmhhbmRsZXJzW25hbWVdICYmIGRlYy5wcm9wcy5oYW5kbGVyc1tuYW1lXVtwcm9wXSlcbiAgICBhY2N1bSA9IHsgLi4uZGVjLnByb3BzLmhhbmRsZXJzW25hbWVdW3Byb3BdLCAuLi5hY2N1bSB9O1xuXG4gIGxldCBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihtKTtcbiAgaWYgKHByb3RvID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gYWNjdW07XG4gIGlmIChwcm90by5jb25zdHJ1Y3Rvci5uYW1lID09PSBuYW1lKSBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cbiAgcmV0dXJuIGdldEhhbmRsZXJBcmdzKGRlYywgcHJvcCwgcHJvdG8sIGFjY3VtKTtcbn07XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7SVJlcG9zaXRvcnk8VD59IHJlcG9cbiAqIEBwYXJhbSBjb250ZXh0XG4gKiBAcGFyYW0ge1R9IG1vZGVsXG4gKiBAcGFyYW0gb3BlcmF0aW9uXG4gKiBAcGFyYW0gcHJlZml4XG4gKlxuICogQHBhcmFtIG9sZE1vZGVsXG4gKiBAZnVuY3Rpb24gZW5mb3JjZURCUHJvcGVydHlEZWNvcmF0b3JzQXN5bmNcbiAqXG4gKiBAbWVtYmVyT2YgZGItZGVjb3JhdG9ycy51dGlsc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5mb3JjZURCRGVjb3JhdG9yczxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBvYmplY3QgPSBvYmplY3QsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4oXG4gIHJlcG86IFIsXG4gIGNvbnRleHQ6IEMsXG4gIG1vZGVsOiBNLFxuICBvcGVyYXRpb246IHN0cmluZyxcbiAgcHJlZml4OiBzdHJpbmcsXG4gIG9sZE1vZGVsPzogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGRlY29yYXRvcnM6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+IHwgdW5kZWZpbmVkID1cbiAgICBnZXREYkRlY29yYXRvcnMobW9kZWwsIG9wZXJhdGlvbiwgcHJlZml4KTtcblxuICBpZiAoIWRlY29yYXRvcnMpIHJldHVybjtcblxuICBmb3IgKGNvbnN0IHByb3AgaW4gZGVjb3JhdG9ycykge1xuICAgIGNvbnN0IGRlY3M6IERlY29yYXRvck1ldGFkYXRhW10gPSBkZWNvcmF0b3JzW3Byb3BdO1xuICAgIGZvciAoY29uc3QgZGVjIG9mIGRlY3MpIHtcbiAgICAgIGNvbnN0IHsga2V5IH0gPSBkZWM7XG4gICAgICBjb25zdCBoYW5kbGVyczogT3BlcmF0aW9uSGFuZGxlcjxNLCBSLCBWLCBGLCBDPltdIHwgdW5kZWZpbmVkID1cbiAgICAgICAgT3BlcmF0aW9ucy5nZXQ8TSwgUiwgViwgRiwgQz4obW9kZWwsIHByb3AsIHByZWZpeCArIGtleSk7XG4gICAgICBpZiAoIWhhbmRsZXJzIHx8ICFoYW5kbGVycy5sZW5ndGgpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCByZWdpc3RlcmVkIGhhbmRsZXIgZm9yIHRoZSBvcGVyYXRpb24gJHtwcmVmaXggKyBrZXl9IHVuZGVyIHByb3BlcnR5ICR7cHJvcH1gXG4gICAgICAgICk7XG5cbiAgICAgIGNvbnN0IGhhbmRsZXJBcmdzID0gZ2V0SGFuZGxlckFyZ3MoZGVjLCBwcm9wLCBtb2RlbCBhcyBhbnkpO1xuXG4gICAgICBpZiAoIWhhbmRsZXJBcmdzIHx8IE9iamVjdC52YWx1ZXMoaGFuZGxlckFyZ3MpLmxlbmd0aCAhPT0gaGFuZGxlcnMubGVuZ3RoKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkFyZ3MgYW5kIGhhbmRsZXJzIGxlbmd0aCBkbyBub3QgbWF0Y2hcIik7XG5cbiAgICAgIGxldCBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPE0sIFIsIFYsIEYsIEM+O1xuICAgICAgbGV0IGRhdGE6IGFueTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGFuZGxlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaGFuZGxlciA9IGhhbmRsZXJzW2ldO1xuICAgICAgICBkYXRhID0gT2JqZWN0LnZhbHVlcyhoYW5kbGVyQXJncylbaV07XG5cbiAgICAgICAgY29uc3QgYXJnczogYW55W10gPSBbY29udGV4dCwgZGF0YS5kYXRhLCBwcm9wLCBtb2RlbF07XG5cbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gT3BlcmF0aW9uS2V5cy5VUERBVEUgJiYgcHJlZml4ID09PSBPcGVyYXRpb25LZXlzLk9OKSB7XG4gICAgICAgICAgaWYgKCFvbGRNb2RlbClcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyBvbGQgbW9kZWwgZm9yIHVwZGF0ZSBvcGVyYXRpb25cIik7XG4gICAgICAgICAgYXJncy5wdXNoKG9sZE1vZGVsKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IChoYW5kbGVyIGFzIFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8TSwgUiwgViwgRiwgQz4pLmFwcGx5KFxuICAgICAgICAgICAgcmVwbyxcbiAgICAgICAgICAgIGFyZ3MgYXMgW0MsIFYsIGtleW9mIE0sIE0sIE1dXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGBGYWlsZWQgdG8gZXhlY3V0ZSBoYW5kbGVyICR7aGFuZGxlci5uYW1lfSBmb3IgJHtwcm9wfSBvbiAke21vZGVsLmNvbnN0cnVjdG9yLm5hbWV9IGR1ZSB0byBlcnJvcjogJHtlfWA7XG4gICAgICAgICAgaWYgKGNvbnRleHQuZ2V0KFwiYnJlYWtPbkhhbmRsZXJFcnJvclwiKSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IobXNnKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogU3BlY2lmaWMgZm9yIERCIERlY29yYXRvcnNcbiAqIEBwYXJhbSB7VH0gbW9kZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gQ1JVRCB7QGxpbmsgT3BlcmF0aW9uS2V5c31cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZXh0cmFQcmVmaXhdXG4gKlxuICogQGZ1bmN0aW9uIGdldERiUHJvcGVydHlEZWNvcmF0b3JzXG4gKlxuICogQG1lbWJlck9mIGRiLWRlY29yYXRvcnMudXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERiRGVjb3JhdG9yczxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogVCxcbiAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gIGV4dHJhUHJlZml4Pzogc3RyaW5nXG4pOiBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YVtdPiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRlY29yYXRvcnM6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+IHwgdW5kZWZpbmVkID1cbiAgICBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIG1vZGVsLFxuICAgICAgLy8gdW5kZWZpbmVkLFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUZMRUNUICsgKGV4dHJhUHJlZml4ID8gZXh0cmFQcmVmaXggOiBcIlwiKVxuICAgICk7XG4gIGlmICghZGVjb3JhdG9ycykgcmV0dXJuO1xuICByZXR1cm4gT2JqZWN0LmtleXMoZGVjb3JhdG9ycykucmVkdWNlKFxuICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT4gfCB1bmRlZmluZWQsIGRlY29yYXRvcikgPT4ge1xuICAgICAgY29uc3QgZGVjID0gZGVjb3JhdG9yc1tkZWNvcmF0b3JdLmZpbHRlcigoZCkgPT4gZC5rZXkgPT09IG9wZXJhdGlvbik7XG4gICAgICBpZiAoZGVjICYmIGRlYy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKCFhY2N1bSkgYWNjdW0gPSB7fTtcbiAgICAgICAgYWNjdW1bZGVjb3JhdG9yXSA9IGRlYztcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LFxuICAgIHVuZGVmaW5lZFxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgZGVjb3JhdG9ycyBmb3IgYW4gb2JqZWN0J3MgcHJvcGVydGllcyBwcmVmaXhlZCBieSB7QHBhcmFtIHByZWZpeGVzfSByZWN1cnNpdmVseVxuICogQHBhcmFtIG1vZGVsXG4gKiBAcGFyYW0gYWNjdW1cbiAqIEBwYXJhbSBwcmVmaXhlc1xuICpcbiAqIEBmdW5jdGlvbiBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5SZXBvc2l0b3J5XG4gKi9cbmV4cG9ydCBjb25zdCBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUgPSBmdW5jdGlvbiA8VCBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IFQsXG4gIGFjY3VtOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9IHwgdW5kZWZpbmVkLFxuICAuLi5wcmVmaXhlczogc3RyaW5nW11cbik6IHsgW2luZGV4ZXI6IHN0cmluZ106IGFueVtdIH0gfCB1bmRlZmluZWQge1xuICBjb25zdCBhY2N1bXVsYXRvciA9IGFjY3VtIHx8IHt9O1xuICBjb25zdCBtZXJnZURlY29yYXRvcnMgPSBmdW5jdGlvbiAoZGVjczogeyBbaW5kZXhlcjogc3RyaW5nXTogYW55W10gfSkge1xuICAgIGNvbnN0IHB1c2hPclNxdWFzaCA9IChrZXk6IHN0cmluZywgLi4udmFsdWVzOiBhbnlbXSkgPT4ge1xuICAgICAgdmFsdWVzLmZvckVhY2goKHZhbCkgPT4ge1xuICAgICAgICBsZXQgbWF0Y2g6IGFueTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICEobWF0Y2ggPSBhY2N1bXVsYXRvcltrZXldLmZpbmQoKGUpID0+IGUua2V5ID09PSB2YWwua2V5KSkgfHxcbiAgICAgICAgICBtYXRjaC5wcm9wcy5vcGVyYXRpb24gIT09IHZhbC5wcm9wcy5vcGVyYXRpb25cbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjdW11bGF0b3Jba2V5XS5wdXNoKHZhbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbC5rZXkgPT09IE1vZGVsS2V5cy5UWVBFKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgeyBoYW5kbGVycywgb3BlcmF0aW9uIH0gPSB2YWwucHJvcHM7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFvcGVyYXRpb24gfHxcbiAgICAgICAgICAhb3BlcmF0aW9uLm1hdGNoKFxuICAgICAgICAgICAgbmV3IFJlZ0V4cChcbiAgICAgICAgICAgICAgYF4oOj8ke09wZXJhdGlvbktleXMuT059fCR7T3BlcmF0aW9uS2V5cy5BRlRFUn0pKDo/JHtPcGVyYXRpb25LZXlzLkNSRUFURX18JHtPcGVyYXRpb25LZXlzLlJFQUR9fCR7T3BlcmF0aW9uS2V5cy5VUERBVEV9fCR7T3BlcmF0aW9uS2V5cy5ERUxFVEV9KSRgXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICBhY2N1bXVsYXRvcltrZXldLnB1c2godmFsKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY2N1bUhhbmRsZXJzID0gbWF0Y2gucHJvcHMuaGFuZGxlcnM7XG5cbiAgICAgICAgT2JqZWN0LmVudHJpZXMoaGFuZGxlcnMpLmZvckVhY2goKFtjbGF6eiwgaGFuZGxlckRlZl0pID0+IHtcbiAgICAgICAgICBpZiAoIShjbGF6eiBpbiBhY2N1bUhhbmRsZXJzKSkge1xuICAgICAgICAgICAgYWNjdW1IYW5kbGVyc1tjbGF6el0gPSBoYW5kbGVyRGVmO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGhhbmRsZXJEZWYgYXMgb2JqZWN0KS5mb3JFYWNoKFxuICAgICAgICAgICAgKFtoYW5kbGVyUHJvcCwgaGFuZGxlcl0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKCEoaGFuZGxlclByb3AgaW4gYWNjdW1IYW5kbGVyc1tjbGF6el0pKSB7XG4gICAgICAgICAgICAgICAgYWNjdW1IYW5kbGVyc1tjbGF6el1baGFuZGxlclByb3BdID0gaGFuZGxlcjtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhoYW5kbGVyIGFzIG9iamVjdCkuZm9yRWFjaChcbiAgICAgICAgICAgICAgICAoW2hhbmRsZXJLZXksIGFyZ3NPYmpdKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoIShoYW5kbGVyS2V5IGluIGFjY3VtSGFuZGxlcnNbY2xhenpdW2hhbmRsZXJQcm9wXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgYWNjdW1IYW5kbGVyc1tjbGF6el1baGFuZGxlclByb3BdW2hhbmRsZXJLZXldID0gYXJnc09iajtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICBgU2tpcHBpbmcgaGFuZGxlciByZWdpc3RyYXRpb24gZm9yICR7Y2xhenp9IHVuZGVyIHByb3AgJHtoYW5kbGVyUHJvcH0gYmVjYXVzZSBoYW5kbGVyIGlzIHRoZSBzYW1lYFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgT2JqZWN0LmVudHJpZXMoZGVjcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBhY2N1bXVsYXRvcltrZXldID0gYWNjdW11bGF0b3Jba2V5XSB8fCBbXTtcbiAgICAgIHB1c2hPclNxdWFzaChrZXksIC4uLnZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBkZWNzOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9IHwgdW5kZWZpbmVkID1cbiAgICBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhtb2RlbCwgLi4ucHJlZml4ZXMpO1xuICBpZiAoZGVjcykgbWVyZ2VEZWNvcmF0b3JzKGRlY3MpO1xuXG4gIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWwpID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gYWNjdW11bGF0b3I7XG5cbiAgLy8gY29uc3QgbmFtZSA9IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWU7XG4gIGNvbnN0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKTtcbiAgaWYgKCFwcm90bykgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAvLyBpZiAocHJvdG8uY29uc3RydWN0b3IgJiYgcHJvdG8uY29uc3RydWN0b3IubmFtZSA9PT0gbmFtZSlcbiAgLy8gICAgIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKVxuICByZXR1cm4gZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlKHByb3RvLCBhY2N1bXVsYXRvciwgLi4ucHJlZml4ZXMpO1xufTtcbiJdfQ==