UNPKG

@decaf-ts/decorator-validation

Version:
146 lines 24.1 kB
import { ModelErrorDefinition } from "./ModelErrorDefinition"; import { Reflection } from "@decaf-ts/reflection"; import { ModelKeys } from "../utils/constants"; import { ReservedModels } from "./constants"; import { VALIDATION_PARENT_KEY } from "../constants"; import { Model } from "./Model"; import { Validation } from "../validation/Validation"; import { ValidationKeys } from "../validation/Validators/constants"; import { PathProxyEngine } from "../utils/PathProxy"; /** * @summary Analyses the decorations of the properties and validates the obj according to them * * @typedef M extends Model * @prop {M} obj Model object to validate * @prop {string[]} [propsToIgnore] object properties to ignore in the validation * * @function validate * @memberOf module:decorator-validation * @category Model */ export function validate(obj, ...propsToIgnore) { const decoratedProperties = []; for (const prop in obj) if (Object.prototype.hasOwnProperty.call(obj, prop) && propsToIgnore.indexOf(prop) === -1) decoratedProperties.push(Reflection.getPropertyDecorators(ValidationKeys.REFLECT, obj, prop)); let result = undefined; for (const decoratedProperty of decoratedProperties) { const { prop, decorators } = decoratedProperty; if (!decorators || !decorators.length) continue; const defaultTypeDecorator = decorators[0]; // tries to find any type decorators or other decorators that already enforce type (the ones with the allowed types property defined). if so, skip the default type verification if (decorators.find((d) => { if (d.key === ValidationKeys.TYPE) return true; return !!d.props.types?.find((t) => t === defaultTypeDecorator.props.name); })) { decorators.shift(); // remove the design:type decorator, since the type will already be checked } let errs = undefined; for (const decorator of decorators) { const validator = Validation.get(decorator.key); if (!validator) { throw new Error(`Missing validator for ${decorator.key}`); } const decoratorProps = decorator.key === ModelKeys.TYPE ? [decorator.props] : decorator.props || {}; const err = validator.hasErrors(obj[prop.toString()], decoratorProps, PathProxyEngine.create(obj, { ignoreUndefined: true, ignoreNull: true })); if (err) { errs = errs || {}; errs[decorator.key] = err; } } if (errs) { result = result || {}; result[decoratedProperty.prop.toString()] = errs; } } // tests nested classes for (const prop of Object.keys(obj).filter((k) => !result || !result[k])) { let err; // if a nested Model const allDecorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, obj, prop).decorators; const decorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, obj, prop).decorators.filter((d) => [ModelKeys.TYPE, ValidationKeys.TYPE].indexOf(d.key) !== -1); if (!decorators || !decorators.length) continue; const dec = decorators.pop(); const clazz = dec.props.name ? [dec.props.name] : Array.isArray(dec.props.customTypes) ? dec.props.customTypes : [dec.props.customTypes]; const reserved = Object.values(ReservedModels).map((v) => v.toLowerCase()); for (const c of clazz) { if (reserved.indexOf(c.toLowerCase()) === -1) { const typeDecoratorKey = Array.isArray(obj[prop]) ? ValidationKeys.LIST : ValidationKeys.TYPE; const types = allDecorators.find((d) => d.key === typeDecoratorKey) || {}; let allowedTypes = []; if (types && types.props) { const customTypes = Array.isArray(obj[prop]) ? types.props.class : types.props.customTypes; if (customTypes) allowedTypes = Array.isArray(customTypes) ? customTypes.map((t) => `${t}`.toLowerCase()) : [customTypes.toLowerCase()]; } const validate = (prop, value) => { if (typeof value !== "object" && typeof value !== "function") return undefined; try { if (value && !value[VALIDATION_PARENT_KEY]) value[VALIDATION_PARENT_KEY] = obj; // TODO: freeze? return Model.isModel(value) ? value.hasErrors() : allowedTypes.includes(typeof value) ? undefined : "Value has no validatable type"; } finally { if (value && value[VALIDATION_PARENT_KEY]) delete value[VALIDATION_PARENT_KEY]; } }; switch (c) { case Array.name: case Set.name: if (allDecorators.length) { const listDec = allDecorators.find((d) => d.key === ValidationKeys.LIST); if (listDec) { err = (c === Array.name ? obj[prop] : // If it's a Set obj[prop].values()) .map((v) => validate(prop, v)) .filter((e) => !!e); if (!err?.length) { // if the result is an empty list... err = undefined; } } } break; default: try { if (obj[prop]) err = validate(prop, obj[prop]); } catch (e) { console.warn(`Model should be validatable but its not: ${e}`); } } } if (err) { result = result || {}; result[prop] = err; } } } return result ? new ModelErrorDefinition(result) : undefined; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2RlbC92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzlELE9BQU8sRUFBcUIsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDckUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXJELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDaEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQU1wRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQ3RCLEdBQU0sRUFDTixHQUFHLGFBQXVCO0lBRTFCLE1BQU0sbUJBQW1CLEdBQTRDLEVBQUUsQ0FBQztJQUN4RSxLQUFLLE1BQU0sSUFBSSxJQUFJLEdBQUc7UUFDcEIsSUFDRSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQztZQUMvQyxhQUFhLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVsQyxtQkFBbUIsQ0FBQyxJQUFJLENBQ3RCLFVBQVUsQ0FBQyxxQkFBcUIsQ0FDOUIsY0FBYyxDQUFDLE9BQU8sRUFDdEIsR0FBRyxFQUNILElBQUksQ0FDb0MsQ0FDM0MsQ0FBQztJQUVOLElBQUksTUFBTSxHQUE0QixTQUFTLENBQUM7SUFF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QUFDO3dCQUNELE1BQU07b0JBQ1I7d0JBQ0UsSUFBSSxDQUFDOzRCQUNILElBQUssR0FBMkIsQ0FBQyxJQUFJLENBQUM7Z0NBQ3BDLEdBQUcsR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFHLEdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUM3QyxDQUFDO3dCQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7NEJBQ3BCLE9BQU8sQ0FBQyxJQUFJLENBQUMsNENBQTRDLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQ2hFLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7WUFDRCxJQUFJLEdBQUcsRUFBRSxDQUFDO2dCQUNSLE1BQU0sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO2dCQUN0QixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBVSxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDL0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE1vZGVsRXJyb3JEZWZpbml0aW9uIH0gZnJvbSBcIi4vTW9kZWxFcnJvckRlZmluaXRpb25cIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBSZXNlcnZlZE1vZGVscyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgVkFMSURBVElPTl9QQVJFTlRfS0VZIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgVmFsaWRhdGFibGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9Nb2RlbFwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbiB9IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vVmFsaWRhdG9ycy9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIE1vZGVsRXJyb3JzLFxuICBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uLFxuICBWYWxpZGF0b3JPcHRpb25zLFxufSBmcm9tIFwiLi4vdmFsaWRhdGlvbi90eXBlc1wiO1xuaW1wb3J0IHsgUGF0aFByb3h5RW5naW5lIH0gZnJvbSBcIi4uL3V0aWxzL1BhdGhQcm94eVwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEFuYWx5c2VzIHRoZSBkZWNvcmF0aW9ucyBvZiB0aGUgcHJvcGVydGllcyBhbmQgdmFsaWRhdGVzIHRoZSBvYmogYWNjb3JkaW5nIHRvIHRoZW1cbiAqXG4gKiBAdHlwZWRlZiBNIGV4dGVuZHMgTW9kZWxcbiAqIEBwcm9wIHtNfSBvYmogTW9kZWwgb2JqZWN0IHRvIHZhbGlkYXRlXG4gKiBAcHJvcCB7c3RyaW5nW119IFtwcm9wc1RvSWdub3JlXSBvYmplY3QgcHJvcGVydGllcyB0byBpZ25vcmUgaW4gdGhlIHZhbGlkYXRpb25cbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGU8TSBleHRlbmRzIE1vZGVsPihcbiAgb2JqOiBNLFxuICAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0aWVzOiBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uW10gPSBbXTtcbiAgZm9yIChjb25zdCBwcm9wIGluIG9iailcbiAgICBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSAmJlxuICAgICAgcHJvcHNUb0lnbm9yZS5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBvYmosXG4gICAgICAgICAgcHJvcFxuICAgICAgICApIGFzIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25cbiAgICAgICk7XG5cbiAgbGV0IHJlc3VsdDogTW9kZWxFcnJvcnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0eSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgeyBwcm9wLCBkZWNvcmF0b3JzIH0gPSBkZWNvcmF0ZWRQcm9wZXJ0eTtcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVmYXVsdFR5cGVEZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhID0gZGVjb3JhdG9yc1swXTtcblxuICAgIC8vIHRyaWVzIHRvIGZpbmQgYW55IHR5cGUgZGVjb3JhdG9ycyBvciBvdGhlciBkZWNvcmF0b3JzIHRoYXQgYWxyZWFkeSBlbmZvcmNlIHR5cGUgKHRoZSBvbmVzIHdpdGggdGhlIGFsbG93ZWQgdHlwZXMgcHJvcGVydHkgZGVmaW5lZCkuIGlmIHNvLCBza2lwIHRoZSBkZWZhdWx0IHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgaWYgKFxuICAgICAgZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuVFlQRSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhIWQucHJvcHMudHlwZXM/LmZpbmQoXG4gICAgICAgICAgKHQpID0+IHQgPT09IGRlZmF1bHRUeXBlRGVjb3JhdG9yLnByb3BzLm5hbWVcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuICAgIH1cblxuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gVmFsaWRhdGlvbi5nZXQoZGVjb3JhdG9yLmtleSk7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvclByb3BzID1cbiAgICAgICAgZGVjb3JhdG9yLmtleSA9PT0gTW9kZWxLZXlzLlRZUEVcbiAgICAgICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICAgICAgOiBkZWNvcmF0b3IucHJvcHMgfHwge307XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICAgICAgKG9iaiBhcyBhbnkpW3Byb3AudG9TdHJpbmcoKV0sXG4gICAgICAgIGRlY29yYXRvclByb3BzIGFzIFZhbGlkYXRvck9wdGlvbnMsXG4gICAgICAgIFBhdGhQcm94eUVuZ2luZS5jcmVhdGUob2JqLCB7IGlnbm9yZVVuZGVmaW5lZDogdHJ1ZSwgaWdub3JlTnVsbDogdHJ1ZSB9KVxuICAgICAgKTtcblxuICAgICAgaWYgKGVycikge1xuICAgICAgICBlcnJzID0gZXJycyB8fCB7fTtcbiAgICAgICAgZXJyc1tkZWNvcmF0b3Iua2V5XSA9IGVycjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJycykge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IHt9O1xuICAgICAgcmVzdWx0W2RlY29yYXRlZFByb3BlcnR5LnByb3AudG9TdHJpbmcoKV0gPSBlcnJzO1xuICAgIH1cbiAgfVxuXG4gIC8vIHRlc3RzIG5lc3RlZCBjbGFzc2VzXG4gIGZvciAoY29uc3QgcHJvcCBvZiBPYmplY3Qua2V5cyhvYmopLmZpbHRlcigoaykgPT4gIXJlc3VsdCB8fCAhcmVzdWx0W2tdKSkge1xuICAgIGxldCBlcnI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAvLyBpZiBhIG5lc3RlZCBNb2RlbFxuICAgIGNvbnN0IGFsbERlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICBvYmosXG4gICAgICBwcm9wXG4gICAgKS5kZWNvcmF0b3JzO1xuICAgIGNvbnN0IGRlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICBvYmosXG4gICAgICBwcm9wXG4gICAgKS5kZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+XG4gICAgICAgIFtNb2RlbEtleXMuVFlQRSwgVmFsaWRhdGlvbktleXMuVFlQRSBhcyBzdHJpbmddLmluZGV4T2YoZC5rZXkpICE9PSAtMVxuICAgICk7XG4gICAgaWYgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgY29udGludWU7XG4gICAgY29uc3QgZGVjID0gZGVjb3JhdG9ycy5wb3AoKSBhcyBEZWNvcmF0b3JNZXRhZGF0YTtcbiAgICBjb25zdCBjbGF6eiA9IGRlYy5wcm9wcy5uYW1lXG4gICAgICA/IFtkZWMucHJvcHMubmFtZV1cbiAgICAgIDogQXJyYXkuaXNBcnJheShkZWMucHJvcHMuY3VzdG9tVHlwZXMpXG4gICAgICAgID8gZGVjLnByb3BzLmN1c3RvbVR5cGVzXG4gICAgICAgIDogW2RlYy5wcm9wcy5jdXN0b21UeXBlc107XG4gICAgY29uc3QgcmVzZXJ2ZWQgPSBPYmplY3QudmFsdWVzKFJlc2VydmVkTW9kZWxzKS5tYXAoKHYpID0+XG4gICAgICB2LnRvTG93ZXJDYXNlKClcbiAgICApIGFzIHN0cmluZ1tdO1xuXG4gICAgZm9yIChjb25zdCBjIG9mIGNsYXp6KSB7XG4gICAgICBpZiAocmVzZXJ2ZWQuaW5kZXhPZihjLnRvTG93ZXJDYXNlKCkpID09PSAtMSkge1xuICAgICAgICBjb25zdCB0eXBlRGVjb3JhdG9yS2V5ID0gQXJyYXkuaXNBcnJheSgob2JqIGFzIGFueSlbcHJvcF0pXG4gICAgICAgICAgPyBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgOiBWYWxpZGF0aW9uS2V5cy5UWVBFO1xuICAgICAgICBjb25zdCB0eXBlczogYW55ID1cbiAgICAgICAgICBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAoZDogeyBrZXk6IHN0cmluZyB9KSA9PiBkLmtleSA9PT0gdHlwZURlY29yYXRvcktleVxuICAgICAgICAgICkgfHwge307XG4gICAgICAgIGxldCBhbGxvd2VkVHlwZXM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGlmICh0eXBlcyAmJiB0eXBlcy5wcm9wcykge1xuICAgICAgICAgIGNvbnN0IGN1c3RvbVR5cGVzID0gQXJyYXkuaXNBcnJheSgob2JqIGFzIGFueSlbcHJvcF0pXG4gICAgICAgICAgICA/IHR5cGVzLnByb3BzLmNsYXNzXG4gICAgICAgICAgICA6IHR5cGVzLnByb3BzLmN1c3RvbVR5cGVzO1xuICAgICAgICAgIGlmIChjdXN0b21UeXBlcylcbiAgICAgICAgICAgIGFsbG93ZWRUeXBlcyA9IEFycmF5LmlzQXJyYXkoY3VzdG9tVHlwZXMpXG4gICAgICAgICAgICAgID8gY3VzdG9tVHlwZXMubWFwKCh0KSA9PiBgJHt0fWAudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICAgICAgOiBbY3VzdG9tVHlwZXMudG9Mb3dlckNhc2UoKV07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWxpZGF0ZSA9IChwcm9wOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBhbnkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAmJiAhdmFsdWVbVkFMSURBVElPTl9QQVJFTlRfS0VZXSlcbiAgICAgICAgICAgICAgdmFsdWVbVkFMSURBVElPTl9QQVJFTlRfS0VZXSA9IG9iajsgLy8gVE9ETzogZnJlZXplP1xuXG4gICAgICAgICAgICByZXR1cm4gTW9kZWwuaXNNb2RlbCh2YWx1ZSlcbiAgICAgICAgICAgICAgPyB2YWx1ZS5oYXNFcnJvcnMoKVxuICAgICAgICAgICAgICA6IGFsbG93ZWRUeXBlcy5pbmNsdWRlcyh0eXBlb2YgdmFsdWUpXG4gICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA6IFwiVmFsdWUgaGFzIG5vIHZhbGlkYXRhYmxlIHR5cGVcIjtcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlW1ZBTElEQVRJT05fUEFSRU5UX0tFWV0pXG4gICAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtWQUxJREFUSU9OX1BBUkVOVF9LRVldO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICBjYXNlIEFycmF5Lm5hbWU6XG4gICAgICAgICAgY2FzZSBTZXQubmFtZTpcbiAgICAgICAgICAgIGlmIChhbGxEZWNvcmF0b3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zdCBsaXN0RGVjID0gYWxsRGVjb3JhdG9ycy5maW5kKFxuICAgICAgICAgICAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChsaXN0RGVjKSB7XG4gICAgICAgICAgICAgICAgZXJyID0gKFxuICAgICAgICAgICAgICAgICAgYyA9PT0gQXJyYXkubmFtZVxuICAgICAgICAgICAgICAgICAgICA/IChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgOiAvLyBJZiBpdCdzIGEgU2V0XG4gICAgICAgICAgICAgICAgICAgICAgKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS52YWx1ZXMoKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHY6IFZhbGlkYXRhYmxlKSA9PiB2YWxpZGF0ZShwcm9wLCB2KSlcbiAgICAgICAgICAgICAgICAgIC5maWx0ZXIoKGU6IGFueSkgPT4gISFlKSBhcyBhbnk7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnI/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBhbiBlbXB0eSBsaXN0Li4uXG4gICAgICAgICAgICAgICAgICBlcnIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0pXG4gICAgICAgICAgICAgICAgZXJyID0gdmFsaWRhdGUocHJvcCwgKG9iaiBhcyBhbnkpW3Byb3BdKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0cyBub3Q6ICR7ZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICAgIHJlc3VsdFtwcm9wXSA9IGVyciBhcyBhbnk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdCA/IG5ldyBNb2RlbEVycm9yRGVmaW5pdGlvbihyZXN1bHQpIDogdW5kZWZpbmVkO1xufVxuIl19