@tsclean/core
Version:
Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.
120 lines • 26 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsContextCreator = void 0;
const helpers_1 = require("../../helpers");
const context_utils_1 = require("../../helpers/context-utils");
const access_1 = require("../../access");
const websockets_1 = require("../../websockets");
const ws_metadata_constants_1 = require("./ws-metadata-constants");
const shared_utils_1 = require("../../utils/shared.utils");
class WsContextCreator {
constructor(wsProxy, exceptionFiltersContext, handlerContextCreator, handlerConsumer, guardsContextCreator, guardsConsumer, interceptorsContextCreator, interceptorsConsumer) {
this.wsProxy = wsProxy;
this.exceptionFiltersContext = exceptionFiltersContext;
this.handlerContextCreator = handlerContextCreator;
this.handlerConsumer = handlerConsumer;
this.guardsContextCreator = guardsContextCreator;
this.guardsConsumer = guardsConsumer;
this.interceptorsContextCreator = interceptorsContextCreator;
this.interceptorsConsumer = interceptorsConsumer;
this.contextUtils = new context_utils_1.ContextUtils();
this.wsParamsFactory = new websockets_1.WsParamsFactory();
this.handlerMetadataStorage = new helpers_1.HandlerMetadataStorage();
}
create(instance, callback, moduleKey, methodName) {
const contextType = 'ws';
const { argsLength, paramtypes, getParamsMetadata } = this.getMetadata(instance, methodName, contextType);
const exceptionHandler = this.exceptionFiltersContext.create(instance, callback, moduleKey);
const pipes = this.handlerContextCreator.create(instance, callback, moduleKey);
const guards = this.guardsContextCreator.create(instance, callback, moduleKey);
const interceptors = this.interceptorsContextCreator.create(instance, callback, moduleKey);
const paramsMetadata = getParamsMetadata(moduleKey);
const paramsOptions = paramsMetadata
? this.contextUtils.mergeParamsMetaTypes(paramsMetadata, paramtypes)
: [];
const fnApplyPipes = this.createPipesFn(pipes, paramsOptions);
const fnCanActivate = this.createGuardsFn(guards, instance, callback, contextType);
const handler = (initialArgs, args) => async () => {
if (fnApplyPipes) {
await fnApplyPipes(initialArgs, ...args);
return callback.apply(instance, initialArgs);
}
return callback.apply(instance, args);
};
const targetPattern = this.reflectCallbackPattern(callback);
return this.wsProxy.create(async (...args) => {
args.push(targetPattern);
const initialArgs = this.contextUtils.createNullArray(argsLength);
fnCanActivate && (await fnCanActivate(args));
return this.interceptorsConsumer.intercept(interceptors, args, instance, callback, handler(initialArgs, args), contextType);
}, exceptionHandler, targetPattern);
}
reflectCallbackParamtypes(instance, callback) {
return Reflect.getMetadata(helpers_1.PARAMTYPES_METADATA, instance, callback.name);
}
reflectCallbackPattern(callback) {
return Reflect.getMetadata(helpers_1.MESSAGE_METADATA, callback);
}
createGuardsFn(guards, instance, callback, contextType) {
const canActivateFn = async (args) => {
const canActivate = await this.guardsConsumer.tryAccess(guards, args, instance, callback, contextType);
if (!canActivate) {
throw new websockets_1.WsException(access_1.FORBIDDEN_MESSAGE);
}
};
return guards.length ? canActivateFn : null;
}
getMetadata(instance, methodName, contextType) {
const cacheMetadata = this.handlerMetadataStorage.get(instance, methodName);
if (cacheMetadata) {
return cacheMetadata;
}
const metadata = this.contextUtils.reflectCallbackMetadata(instance, methodName, helpers_1.PARAM_ARGS_METADATA) || ws_metadata_constants_1.DEFAULT_CALLBACK_METADATA;
const keys = Object.keys(metadata);
const argsLength = this.contextUtils.getArgumentsLength(keys, metadata);
const paramtypes = this.contextUtils.reflectCallbackParamTypes(instance, methodName);
const contextFactory = this.contextUtils.getContextFactory(contextType, instance, instance[methodName]);
const getParamsMetadata = (moduleKey) => this.exchangeKeysForValues(keys, metadata, moduleKey, this.wsParamsFactory, contextFactory);
const handlerMetadata = {
argsLength,
paramtypes,
getParamsMetadata
};
this.handlerMetadataStorage.set(instance, methodName, handlerMetadata);
return handlerMetadata;
}
exchangeKeysForValues(keys, metadata, moduleContext, paramsFactory, contextFactory) {
this.handlerContextCreator.setModuleContext(moduleContext);
return keys.map(key => {
const { index, data, handlers: pipesCollection } = metadata[key];
const handlers = this.handlerContextCreator.createConcreteContext(pipesCollection);
const type = this.contextUtils.mapParamType(key);
if (key.includes(helpers_1.CUSTOM_ROUTE_AGRS_METADATA)) {
const { factory } = metadata[key];
const customExtractValue = this.contextUtils.getCustomFactory(factory, data, contextFactory);
return { index, extractValue: customExtractValue, type, data, handlers };
}
const numericType = Number(type);
const extractValue = (...args) => paramsFactory.exchangeKeyForValue(numericType, data, args);
return { index, extractValue, type: numericType, data, handlers };
});
}
createPipesFn(handler, paramsOptions) {
const pipesFn = async (args, ...params) => {
const resolveParamValue = async (param) => {
const { index, extractValue, type, data, metaType, handlers: paramPipes } = param;
const value = extractValue(...params);
args[index] = await this.getParamValue(value, { metaType, type, data }, handler.concat(paramPipes));
};
await Promise.all(paramsOptions.map(resolveParamValue));
};
return paramsOptions.length ? pipesFn : null;
}
async getParamValue(value, { metaType, type, data }, pipes) {
return (0, shared_utils_1.isEmpty)(pipes)
? value
: this.handlerConsumer.apply(value, { metaType, type, data }, pipes);
}
}
exports.WsContextCreator = WsContextCreator;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MtY29udGV4dC1jcmVhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3dlYnNvY2tldHMvY29udGV4dC93cy1jb250ZXh0LWNyZWF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBT3NCO0FBQ3RCLCtEQUEyRTtBQUczRSx5Q0FJcUI7QUFDckIsaURBS3lCO0FBT3pCLG1FQUFtRTtBQUNuRSwyREFBa0Q7QUFTbEQsTUFBYSxnQkFBZ0I7SUFNM0IsWUFDbUIsT0FBZ0IsRUFDaEIsdUJBQWdELEVBQ2hELHFCQUE0QyxFQUM1QyxlQUFnQyxFQUNoQyxvQkFBa0QsRUFDbEQsY0FBc0MsRUFDdEMsMEJBQXNELEVBQ3RELG9CQUEwQztRQVAxQyxZQUFPLEdBQVAsT0FBTyxDQUFTO1FBQ2hCLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQUM1QyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUE4QjtRQUNsRCxtQkFBYyxHQUFkLGNBQWMsQ0FBd0I7UUFDdEMsK0JBQTBCLEdBQTFCLDBCQUEwQixDQUE0QjtRQUN0RCx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBYjVDLGlCQUFZLEdBQUcsSUFBSSw0QkFBWSxFQUFFLENBQUE7UUFDakMsb0JBQWUsR0FBRyxJQUFJLDRCQUFlLEVBQUUsQ0FBQTtRQUN2QywyQkFBc0IsR0FDckMsSUFBSSxnQ0FBc0IsRUFBcUIsQ0FBQTtJQVc5QyxDQUFDO0lBRUcsTUFBTSxDQUNYLFFBQXdCLEVBQ3hCLFFBQXNDLEVBQ3RDLFNBQWlCLEVBQ2pCLFVBQWtCO1FBRWxCLE1BQU0sV0FBVyxHQUFnQixJQUFJLENBQUE7UUFDckMsTUFBTSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUNwRSxRQUFRLEVBQ1Is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LE9BQU8sYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7SUFDOUMsQ0FBQztJQUVNLEtBQUssQ0FBQyxhQUFhLENBQ3hCLEtBQVEsRUFDUixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUEyQyxFQUNqRSxLQUF5QjtRQUV6QixPQUFPLElBQUEsc0JBQU8sRUFBQyxLQUFLLENBQUM7WUFDbkIsQ0FBQyxDQUFDLEtBQUs7WUFDUCxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUN4RSxDQUFDO0NBQ0Y7QUE5T0QsNENBOE9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ1VTVE9NX1JPVVRFX0FHUlNfTUVUQURBVEEsXG4gIEV4ZWN1dGlvbkNvbnRleHRIb3N0LFxuICBIYW5kbGVyTWV0YWRhdGFTdG9yYWdlLFxuICBNRVNTQUdFX01FVEFEQVRBLFxuICBQQVJBTV9BUkdTX01FVEFEQVRBLFxuICBQQVJBTVRZUEVTX01FVEFEQVRBXG59IGZyb20gJy4uLy4uL2hlbHBlcnMnXG5pbXBvcnQgeyBDb250ZXh0VXRpbHMsIFBhcmFtUHJvcGVydGllcyB9IGZyb20gJy4uLy4uL2hlbHBlcnMvY29udGV4dC11dGlscydcbmltcG9ydCB7IEV4Y2VwdGlvbkZpbHRlcnNDb250ZXh0IH0gZnJvbSAnLi9leGNlcHRpb24tZmlsdGVycy1jb250ZXh0J1xuaW1wb3J0IHsgQ29udGV4dFR5cGUsIENvbnRyb2xsZXJUeXBlIH0gZnJvbSAnLi4vLi4vdHlwZXMnXG5pbXBvcnQge1xuICBBY2Nlc3NSZXNvdXJjZUNvbnN1bWVyLFxuICBBY2Nlc3NSZXNvdXJjZUNvbnRleHRDcmVhdG9yLFxuICBGT1JCSURERU5fTUVTU0FHRVxufSBmcm9tICcuLi8uLi9hY2Nlc3MnXG5pbXBvcnQge1xuICBIYW5kbGVyQ29uc3VtZXIsXG4gIFdzRXhjZXB0aW9uLFxuICBIYW5kbGVyQ29udGV4dENyZWF0b3IsXG4gIFdzUGFyYW1zRmFjdG9yeVxufSBmcm9tICcuLi8uLi93ZWJzb2NrZXRzJ1xuaW1wb3J0IHsgSGFuZGxlclRyYW5zZm9ybSwgUGFyYW1zTWV0YWRhdGFJbnRlcmZhY2UgfSBmcm9tICcuLi8uLi9jb250cmFjdHMnXG5pbXBvcnQge1xuICBJbnRlcmNlcHRvcnNDb25zdW1lcixcbiAgSW50ZXJjZXB0b3JzQ29udGV4dENyZWF0b3Jcbn0gZnJvbSAnLi4vLi4vaW50ZXJjZXB0b3JzJ1xuaW1wb3J0IHsgV3NQcm94eSB9IGZyb20gJy4vd3MtcHJveHknXG5pbXBvcnQgeyBERUZBVUxUX0NBTExCQUNLX01FVEFEQVRBIH0gZnJvbSAnLi93cy1tZXRhZGF0YS1jb25zdGFudHMnXG5pbXBvcnQgeyBpc0VtcHR5IH0gZnJvbSAnLi4vLi4vdXRpbHMvc2hhcmVkLnV0aWxzJ1xuXG50eXBlIFdzUGFyYW1Qcm9wZXJ0aWVzID0gUGFyYW1Qcm9wZXJ0aWVzICYgeyBtZXRhdHlwZT86IGFueSB9XG5leHBvcnQgaW50ZXJmYWNlIFdzSGFuZGxlck1ldGFkYXRhIHtcbiAgYXJnc0xlbmd0aDogbnVtYmVyXG4gIHBhcmFtdHlwZXM6IGFueVtdXG4gIGdldFBhcmFtc01ldGFkYXRhOiAobW9kdWxlS2V5OiBzdHJpbmcpID0+IFdzUGFyYW1Qcm9wZXJ0aWVzW11cbn1cblxuZXhwb3J0IGNsYXNzIFdzQ29udGV4dENyZWF0b3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbnRleHRVdGlscyA9IG5ldyBDb250ZXh0VXRpbHMoKVxuICBwcml2YXRlIHJlYWRvbmx5IHdzUGFyYW1zRmFjdG9yeSA9IG5ldyBXc1BhcmFtc0ZhY3RvcnkoKVxuICBwcml2YXRlIHJlYWRvbmx5IGhhbmRsZXJNZXRhZGF0YVN0b3JhZ2UgPVxuICAgIG5ldyBIYW5kbGVyTWV0YWRhdGFTdG9yYWdlPFdzSGFuZGxlck1ldGFkYXRhPigpXG5cbiAgY29uc3RydWN0b3IgKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgd3NQcm94eTogV3NQcm94eSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGV4Y2VwdGlvbkZpbHRlcnNDb250ZXh0OiBFeGNlcHRpb25GaWx0ZXJzQ29udGV4dCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhhbmRsZXJDb250ZXh0Q3JlYXRvcjogSGFuZGxlckNvbnRleHRDcmVhdG9yLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaGFuZGxlckNvbnN1bWVyOiBIYW5kbGVyQ29uc3VtZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBndWFyZHNDb250ZXh0Q3JlYXRvcjogQWNjZXNzUmVzb3VyY2VDb250ZXh0Q3JlYXRvcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGd1YXJkc0NvbnN1bWVyOiBBY2Nlc3NSZXNvdXJjZUNvbnN1bWVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW50ZXJjZXB0b3JzQ29udGV4dENyZWF0b3I6IEludGVyY2VwdG9yc0NvbnRleHRDcmVhdG9yLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW50ZXJjZXB0b3JzQ29uc3VtZXI6IEludGVyY2VwdG9yc0NvbnN1bWVyXG4gICkge31cblxuICBwdWJsaWMgY3JlYXRlPFQgZXh0ZW5kcyBQYXJhbXNNZXRhZGF0YUludGVyZmFjZSA9IFBhcmFtc01ldGFkYXRhSW50ZXJmYWNlPiAoXG4gICAgaW5zdGFuY2U6IENvbnRyb2xsZXJUeXBlLFxuICAgIGNhbGxiYWNrOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkLFxuICAgIG1vZHVsZUtleTogc3RyaW5nLFxuICAgIG1ldGhvZE5hbWU6IHN0cmluZ1xuICApOiAoLi4uYXJnczogYW55W10pID0+IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbnRleHRUeXBlOiBDb250ZXh0VHlwZSA9ICd3cydcbiAgICBjb25zdCB7IGFyZ3NMZW5ndGgsIHBhcmFtdHlwZXMsIGdldFBhcmFtc01ldGFkYXRhIH0gPSB0aGlzLmdldE1ldGFkYXRhPFQ+KFxuICAgICAgaW5zdGFuY2UsXG4gICAgICBtZXRob2ROYW1lLFxuICAgICAgY29udGV4dFR5cGVcbiAgICApXG4gICAgY29uc3QgZXhjZXB0aW9uSGFuZGxlciA9IHRoaXMuZXhjZXB0aW9uRmlsdGVyc0NvbnRleHQuY3JlYXRlKFxuICAgICAgaW5zdGFuY2UsXG4gICAgICBjYWxsYmFjayxcbiAgICAgIG1vZHVsZUtleVxuICAgIClcbiAgICBjb25zdCBwaXBlcyA9IHRoaXMuaGFuZGxlckNvbnRleHRDcmVhdG9yLmNyZWF0ZShcbiAgICAgIGluc3RhbmNlLFxuICAgICAgY2FsbGJhY2ssXG4gICAgICBtb2R1bGVLZXlcbiAgICApXG4gICAgY29uc3QgZ3VhcmRzID0gdGhpcy5ndWFyZHNDb250ZXh0Q3JlYXRvci5jcmVhdGUoXG4gICAgICBpbnN0YW5jZSxcbiAgICAgIGNhbGxiYWNrLFxuICAgICAgbW9kdWxlS2V5XG4gICAgKVxuICAgIGNvbnN0IGludGVyY2VwdG9ycyA9IHRoaXMuaW50ZXJjZXB0b3JzQ29udGV4dENyZWF0b3IuY3JlYXRlKFxuICAgICAgaW5zdGFuY2UsXG4gICAgICBjYWxsYmFjayxcbiAgICAgIG1vZHVsZUtleVxuICAgIClcblxuICAgIGNvbnN0IHBhcmFtc01ldGFkYXRhID0gZ2V0UGFyYW1zTWV0YWRhdGEobW9kdWxlS2V5KVxuICAgIGNvbnN0IHBhcmFtc09wdGlvbnMgPSBwYXJhbXNNZXRhZGF0YVxuICAgICAgPyB0aGlzLmNvbnRleHRVdGlscy5tZXJnZVBhcmFtc01ldGFUeXBlcyhwYXJhbXNNZXRhZGF0YSwgcGFyYW10eXBlcylcbiAgICAgIDogW11cbiAgICBjb25zdCBmbkFwcGx5UGlwZXMgPSB0aGlzLmNyZWF0ZVBpcGVzRm4ocGlwZXMsIHBhcmFtc09wdGlvbnMpXG5cbiAgICBjb25zdCBmbkNhbkFjdGl2YXRlID0gdGhpcy5jcmVhdGVHdWFyZHNGbihcbiAgICAgIGd1YXJkcyxcbiAgICAgIGluc3RhbmNlLFxuICAgICAgY2FsbGJhY2ssXG4gICAgICBjb250ZXh0VHlwZVxuICAgIClcblxuICAgIGNvbnN0IGhhbmRsZXIgPSAoaW5pdGlhbEFyZ3M6IHVua25vd25bXSwgYXJnczogdW5rbm93bltdKSA9PiBhc3luYyAoKSA9PiB7XG4gICAgICBpZiAoZm5BcHBseVBpcGVzKSB7XG4gICAgICAgIGF3YWl0IGZuQXBwbHlQaXBlcyhpbml0aWFsQXJncywgLi4uYXJncylcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGluc3RhbmNlLCBpbml0aWFsQXJncylcbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseShpbnN0YW5jZSwgYXJncylcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0UGF0dGVybiA9IHRoaXMucmVmbGVjdENhbGxiYWNrUGF0dGVybihjYWxsYmFjaylcbiAgICByZXR1cm4gdGhpcy53c1Byb3h5LmNyZWF0ZShcbiAgICAgIGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgYXJncy5wdXNoKHRhcmdldFBhdHRlcm4pXG5cbiAgICAgICAgY29uc3QgaW5pdGlhbEFyZ3MgPSB0aGlzLmNvbnRleHRVdGlscy5jcmVhdGVOdWxsQXJyYXkoYXJnc0xlbmd0aClcbiAgICAgICAgZm5DYW5BY3RpdmF0ZSAmJiAoYXdhaXQgZm5DYW5BY3RpdmF0ZShhcmdzKSlcblxuICAgICAgICByZXR1cm4gdGhpcy5pbnRlcmNlcHRvcnNDb25zdW1lci5pbnRlcmNlcHQoXG4gICAgICAgICAgaW50ZXJjZXB0b3JzLFxuICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgaGFuZGxlcihpbml0aWFsQXJncywgYXJncyksXG4gICAgICAgICAgY29udGV4dFR5cGVcbiAgICAgICAgKVxuICAgICAgfSxcbiAgICAgIGV4Y2VwdGlvbkhhbmRsZXIsXG4gICAgICB0YXJnZXRQYXR0ZXJuXG4gICAgKVxuICB9XG5cbiAgcHVibGljIHJlZmxlY3RDYWxsYmFja1BhcmFtdHlwZXMgKFxuICAgIGluc3RhbmNlOiBDb250cm9sbGVyVHlwZSxcbiAgICBjYWxsYmFjazogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnlcbiAgKTogYW55W10ge1xuICAgIHJldHVybiBSZWZsZWN0LmdldE1ldGFkYXRhKFBBUkFNVFlQRVNfTUVUQURBVEEsIGluc3RhbmNlLCBjYWxsYmFjay5uYW1lKVxuICB9XG5cbiAgcHVibGljIHJlZmxlY3RDYWxsYmFja1BhdHRlcm4gKGNhbGxiYWNrOiAoLi4uYXJnczogYW55W10pID0+IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVTU0FHRV9NRVRBREFUQSwgY2FsbGJhY2spXG4gIH1cblxuICBwdWJsaWMgY3JlYXRlR3VhcmRzRm48VENvbnRleHQgZXh0ZW5kcyBzdHJpbmcgPSBDb250ZXh0VHlwZT4gKFxuICAgIGd1YXJkczogYW55W10sXG4gICAgaW5zdGFuY2U6IENvbnRyb2xsZXJUeXBlLFxuICAgIGNhbGxiYWNrOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBhbnksXG4gICAgY29udGV4dFR5cGU/OiBUQ29udGV4dFxuICApOiBGdW5jdGlvbiB8IG51bGwge1xuICAgIGNvbnN0IGNhbkFjdGl2YXRlRm4gPSBhc3luYyAoYXJnczogYW55W10pID0+IHtcbiAgICAgIGNvbnN0IGNhbkFjdGl2YXRlID0gYXdhaXQgdGhpcy5ndWFyZHNDb25zdW1lci50cnlBY2Nlc3M8VENvbnRleHQ+KFxuICAgICAgICBndWFyZHMsXG4gICAgICAgIGFyZ3MsXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgY29udGV4dFR5cGVcbiAgICAgIClcbiAgICAgIGlmICghY2FuQWN0aXZhdGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFdzRXhjZXB0aW9uKEZPUkJJRERFTl9NRVNTQUdFKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZ3VhcmRzLmxlbmd0aCA/IGNhbkFjdGl2YXRlRm4gOiBudWxsXG4gIH1cblxuICBwdWJsaWMgZ2V0TWV0YWRhdGE8VE1ldGFkYXRhLCBUQ29udGV4dCBleHRlbmRzIENvbnRleHRUeXBlID0gQ29udGV4dFR5cGU+IChcbiAgICBpbnN0YW5jZTogQ29udHJvbGxlclR5cGUsXG4gICAgbWV0aG9kTmFtZTogc3RyaW5nLFxuICAgIGNvbnRleHRUeXBlOiBUQ29udGV4dFxuICApOiBXc0hhbmRsZXJNZXRhZGF0YSB7XG4gICAgY29uc3QgY2FjaGVNZXRhZGF0YSA9IHRoaXMuaGFuZGxlck1ldGFkYXRhU3RvcmFnZS5nZXQoaW5zdGFuY2UsIG1ldGhvZE5hbWUpXG4gICAgaWYgKGNhY2hlTWV0YWRhdGEpIHtcbiAgICAgIHJldHVybiBjYWNoZU1ldGFkYXRhXG4gICAgfVxuICAgIGNvbnN0IG1ldGFkYXRhID1cbiAgICAgIHRoaXMuY29udGV4dFV0aWxzLnJlZmxlY3RDYWxsYmFja01ldGFkYXRhPFRNZXRhZGF0YT4oXG4gICAgICAgIGluc3RhbmNlLFxuICAgICAgICBtZXRob2ROYW1lLFxuICAgICAgICBQQVJBTV9BUkdTX01FVEFEQVRBXG4gICAgICApIHx8IERFRkFVTFRfQ0FMTEJBQ0tfTUVUQURBVEFcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMobWV0YWRhdGEpXG4gICAgY29uc3QgYXJnc0xlbmd0aCA9IHRoaXMuY29udGV4dFV0aWxzLmdldEFyZ3VtZW50c0xlbmd0aChrZXlzLCBtZXRhZGF0YSlcbiAgICBjb25zdCBwYXJhbXR5cGVzID0gdGhpcy5jb250ZXh0VXRpbHMucmVmbGVjdENhbGxiYWNrUGFyYW1UeXBlcyhcbiAgICAgIGluc3RhbmNlLFxuICAgICAgbWV0aG9kTmFtZVxuICAgIClcbiAgICBjb25zdCBjb250ZXh0RmFjdG9yeSA9IHRoaXMuY29udGV4dFV0aWxzLmdldENvbnRleHRGYWN0b3J5KFxuICAgICAgY29udGV4dFR5cGUsXG4gICAgICBpbnN0YW5jZSxcbiAgICAgIGluc3RhbmNlW21ldGhvZE5hbWVdXG4gICAgKVxuICAgIGNvbnN0IGdldFBhcmFtc01ldGFkYXRhID0gKG1vZHVsZUtleTogc3RyaW5nKSA9PlxuICAgICAgdGhpcy5leGNoYW5nZUtleXNGb3JWYWx1ZXMoXG4gICAgICAgIGtleXMsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICBtb2R1bGVLZXksXG4gICAgICAgIHRoaXMud3NQYXJhbXNGYWN0b3J5LFxuICAgICAgICBjb250ZXh0RmFjdG9yeVxuICAgICAgKVxuXG4gICAgY29uc3QgaGFuZGxlck1ldGFkYXRhOiBXc0hhbmRsZXJNZXRhZGF0YSA9IHtcbiAgICAgIGFyZ3NMZW5ndGgsXG4gICAgICBwYXJhbXR5cGVzLFxuICAgICAgZ2V0UGFyYW1zTWV0YWRhdGFcbiAgICB9XG4gICAgdGhpcy5oYW5kbGVyTWV0YWRhdGFTdG9yYWdlLnNldChpbnN0YW5jZSwgbWV0aG9kTmFtZSwgaGFuZGxlck1ldGFkYXRhKVxuICAgIHJldHVybiBoYW5kbGVyTWV0YWRhdGFcbiAgfVxuXG4gIHB1YmxpYyBleGNoYW5nZUtleXNGb3JWYWx1ZXM8VE1ldGFkYXRhID0gYW55PiAoXG4gICAga2V5czogc3RyaW5nW10sXG4gICAgbWV0YWRhdGE6IFRNZXRhZGF0YSxcbiAgICBtb2R1bGVDb250ZXh0OiBzdHJpbmcsXG4gICAgcGFyYW1zRmFjdG9yeTogV3NQYXJhbXNGYWN0b3J5LFxuICAgIGNvbnRleHRGYWN0b3J5OiAoYXJnczogdW5rbm93bltdKSA9PiBFeGVjdXRpb25Db250ZXh0SG9zdFxuICApOiBQYXJhbVByb3BlcnRpZXNbXSB7XG4gICAgdGhpcy5oYW5kbGVyQ29udGV4dENyZWF0b3Iuc2V0TW9kdWxlQ29udGV4dChtb2R1bGVDb250ZXh0KVxuXG4gICAgcmV0dXJuIGtleXMubWFwKGtleSA9PiB7XG4gICAgICBjb25zdCB7IGluZGV4LCBkYXRhLCBoYW5kbGVyczogcGlwZXNDb2xsZWN0aW9uIH0gPSBtZXRhZGF0YVtrZXldXG4gICAgICBjb25zdCBoYW5kbGVycyA9XG4gICAgICAgIHRoaXMuaGFuZGxlckNvbnRleHRDcmVhdG9yLmNyZWF0ZUNvbmNyZXRlQ29udGV4dChwaXBlc0NvbGxlY3Rpb24pXG4gICAgICBjb25zdCB0eXBlID0gdGhpcy5jb250ZXh0VXRpbHMubWFwUGFyYW1UeXBlKGtleSlcblxuICAgICAgaWYgKGtleS5pbmNsdWRlcyhDVVNUT01fUk9VVEVfQUdSU19NRVRBREFUQSkpIHtcbiAgICAgICAgY29uc3QgeyBmYWN0b3J5IH0gPSBtZXRhZGF0YVtrZXldXG4gICAgICAgIGNvbnN0IGN1c3RvbUV4dHJhY3RWYWx1ZSA9IHRoaXMuY29udGV4dFV0aWxzLmdldEN1c3RvbUZhY3RvcnkoXG4gICAgICAgICAgZmFjdG9yeSxcbiAgICAgICAgICBkYXRhLFxuICAgICAgICAgIGNvbnRleHRGYWN0b3J5XG4gICAgICAgIClcbiAgICAgICAgcmV0dXJuIHsgaW5kZXgsIGV4dHJhY3RWYWx1ZTogY3VzdG9tRXh0cmFjdFZhbHVlLCB0eXBlLCBkYXRhLCBoYW5kbGVycyB9XG4gICAgICB9XG4gICAgICBjb25zdCBudW1lcmljVHlwZSA9IE51bWJlcih0eXBlKVxuICAgICAgY29uc3QgZXh0cmFjdFZhbHVlID0gKC4uLmFyZ3M6IGFueVtdKSA9PlxuICAgICAgICBwYXJhbXNGYWN0b3J5LmV4Y2hhbmdlS2V5Rm9yVmFsdWUobnVtZXJpY1R5cGUsIGRhdGEsIGFyZ3MpXG5cbiAgICAgIHJldHVybiB7IGluZGV4LCBleHRyYWN0VmFsdWUsIHR5cGU6IG51bWVyaWNUeXBlLCBkYXRhLCBoYW5kbGVycyB9XG4gICAgfSlcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVQaXBlc0ZuIChcbiAgICBoYW5kbGVyOiBIYW5kbGVyVHJhbnNmb3JtW10sXG4gICAgcGFyYW1zT3B0aW9uczogKFBhcmFtUHJvcGVydGllcyAmIHsgbWV0YVR5cGU/OiB1bmtub3duIH0pW11cbiAgKSB7XG4gICAgY29uc3QgcGlwZXNGbiA9IGFzeW5jIChhcmdzOiB1bmtub3duW10sIC4uLnBhcmFtczogdW5rbm93bltdKSA9PiB7XG4gICAgICBjb25zdCByZXNvbHZlUGFyYW1WYWx1ZSA9IGFzeW5jIChcbiAgICAgICAgcGFyYW06IFBhcmFtUHJvcGVydGllcyAmIHsgbWV0YVR5cGU/OiB1bmtub3duIH1cbiAgICAgICkgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgZXh0cmFjdFZhbHVlLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBtZXRhVHlwZSxcbiAgICAgICAgICBoYW5kbGVyczogcGFyYW1QaXBlc1xuICAgICAgICB9ID0gcGFyYW1cbiAgICAgICAgY29uc3QgdmFsdWUgPSBleHRyYWN0VmFsdWUoLi4ucGFyYW1zKVxuXG4gICAgICAgIGFyZ3NbaW5kZXhdID0gYXdhaXQgdGhpcy5nZXRQYXJhbVZhbHVlKFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIHsgbWV0YVR5cGUsIHR5cGUsIGRhdGEgfSxcbiAgICAgICAgICBoYW5kbGVyLmNvbmNhdChwYXJhbVBpcGVzKVxuICAgICAgICApXG4gICAgICB9XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChwYXJhbXNPcHRpb25zLm1hcChyZXNvbHZlUGFyYW1WYWx1ZSkpXG4gICAgfVxuICAgIHJldHVybiBwYXJhbXNPcHRpb25zLmxlbmd0aCA/IHBpcGVzRm4gOiBudWxsXG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0UGFyYW1WYWx1ZTxUPiAoXG4gICAgdmFsdWU6IFQsXG4gICAgeyBtZXRhVHlwZSwgdHlwZSwgZGF0YSB9OiB7IG1ldGFUeXBlOiBhbnk7IHR5cGU6IGFueTsgZGF0YTogYW55IH0sXG4gICAgcGlwZXM6IEhhbmRsZXJUcmFuc2Zvcm1bXVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBpc0VtcHR5KHBpcGVzKVxuICAgICAgPyB2YWx1ZVxuICAgICAgOiB0aGlzLmhhbmRsZXJDb25zdW1lci5hcHBseSh2YWx1ZSwgeyBtZXRhVHlwZSwgdHlwZSwgZGF0YSB9LCBwaXBlcylcbiAgfVxufVxuIl19