UNPKG

@tsclean/core

Version:

Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.

159 lines 35.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExternalContextCreator = void 0; const core_1 = require("../core"); const access_1 = require("../access"); const interceptors_1 = require("../interceptors"); const context_utils_1 = require("./context-utils"); const external_proxy_1 = require("./external-proxy"); const handler_metadata_storage_1 = require("./handler-metadata-storage"); const constants_1 = require("./constants"); const utils_1 = require("../utils"); const exceptions_1 = require("../exceptions"); const rxjs_1 = require("rxjs"); class ExternalContextCreator { constructor(accessResourceContextCreator, accessResourceConsumer, interceptorsContextCreator, interceptorsConsumer, modulesContainer, handlersContextCreator, handlersConsumer, filtersContextCreator) { this.accessResourceContextCreator = accessResourceContextCreator; this.accessResourceConsumer = accessResourceConsumer; this.interceptorsContextCreator = interceptorsContextCreator; this.interceptorsConsumer = interceptorsConsumer; this.modulesContainer = modulesContainer; this.handlersContextCreator = handlersContextCreator; this.handlersConsumer = handlersConsumer; this.filtersContextCreator = filtersContextCreator; this.contextUtils = new context_utils_1.ContextUtils(); this.externalErrorProxy = new external_proxy_1.ExternalErrorProxy(); this.handlerMetadataStorage = new handler_metadata_storage_1.HandlerMetadataStorage(); } static fromContainer(container) { const accessResourceContextCreator = new access_1.AccessResourceContextCreator(container, container.applicationConfig); const accessResourceConsumer = new access_1.AccessResourceConsumer(); const interceptorsContextCreator = new interceptors_1.InterceptorsContextCreator(container, container.applicationConfig); const interceptorsConsumer = new interceptors_1.InterceptorsConsumer(); const handlersContextCreator = new core_1.HandlersContextCreator(container, container.applicationConfig); const handlersConsumer = new core_1.HandlersConsumer(); const filtersContextCreator = new core_1.ExternalExceptionFilterContext(container, container.applicationConfig); const externalContextCreator = new ExternalContextCreator(accessResourceContextCreator, accessResourceConsumer, interceptorsContextCreator, interceptorsConsumer, container.getModules(), handlersContextCreator, handlersConsumer, filtersContextCreator); externalContextCreator.container = container; return externalContextCreator; } create(instance, callback, methodName, metadataKey, paramsFactory, contextId = core_1.STATIC_CONTEXT, inquirerId, options = { interceptors: true, resources: true, filters: true, }, contextType = 'http') { const module = this.getContextModuleKey(instance.constructor); const { argsLength, paramTypes, getParamsMetadata } = this.getMetadata(instance, methodName, metadataKey, paramsFactory, contextType); const handlers = this.handlersContextCreator.create(instance, callback, module, contextId, inquirerId); const resources = this.accessResourceContextCreator.create(instance, callback, module, contextId, inquirerId); const exceptionFilter = this.filtersContextCreator.create(instance, callback, module, contextId, inquirerId); const interceptors = options.interceptors ? this.interceptorsContextCreator.create(instance, callback, module, contextId, inquirerId) : []; const paramsMetadata = getParamsMetadata(module, contextId, inquirerId); const paramsOptions = paramsMetadata ? this.contextUtils.mergeParamsMetaTypes(paramsMetadata, paramTypes) : []; const fnAccessResource = options.resources ? this.createAccessResourceFn(resources, instance, callback, contextType) : null; const fnApplyHandlers = this.createHandlersFn(handlers, paramsOptions); const handler = (initialArgs, ...args) => async () => { if (fnApplyHandlers) { await fnApplyHandlers(initialArgs, ...args); return callback.apply(instance, initialArgs); } return callback.apply(instance, args); }; const target = async (...args) => { const initialArgs = this.contextUtils.createNullArray(argsLength); fnAccessResource && (await fnAccessResource(args)); const result = await this.interceptorsConsumer.intercept(interceptors, args, instance, callback, handler(initialArgs, ...args), contextType); return this.transformToResult(result); }; return options.filters ? this.externalErrorProxy.createProxy(target, exceptionFilter, contextType) : target; } getMetadata(instance, methodName, metadataKey, paramsFactory, contextType) { const cacheMetadata = this.handlerMetadataStorage.get(instance, methodName); if (cacheMetadata) return cacheMetadata; const metadata = this.contextUtils.reflectCallbackMetadata(instance, methodName, metadataKey || '') || {}; 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, contextId = core_1.STATIC_CONTEXT, inquirerId) => paramsFactory ? this.exchangeKeysForValues(keys, metadata, moduleKey, paramsFactory, contextId, inquirerId, contextFactory) : null; const handlerMetadata = { argsLength, paramTypes, getParamsMetadata, }; this.handlerMetadataStorage.set(instance, methodName, handlerMetadata); return handlerMetadata; } getContextModuleKey(moduleCtor) { const emptyModuleKey = ''; if (!moduleCtor) { return emptyModuleKey; } const moduleContainerEntries = this.modulesContainer.entries(); for (const [key, moduleRef] of moduleContainerEntries) { if (moduleRef.hasProvider(moduleCtor)) { return key; } } return emptyModuleKey; } exchangeKeysForValues(keys, metadata, moduleContext, paramsFactory, contextId = core_1.STATIC_CONTEXT, inquirerId, contextFactory = this.contextUtils.getContextFactory('http')) { this.handlersContextCreator.setModuleContext(moduleContext); return keys.map(key => { const { index, data, handlers: handlersCollection } = metadata[key]; const handlers = this.handlersContextCreator.createConcreteContext(handlersCollection, contextId, inquirerId); const type = this.contextUtils.mapParamType(key); if (key.includes(constants_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 }; }); } createHandlersFn(pipes, paramsOptions) { const handlerFn = async (args, ...params) => { const resolveParamValue = async (param) => { const { index, extractValue, type, data, metaType, handlers: paramHandlers, } = param; const value = extractValue(...params); args[index] = await this.getParamValue(value, { metaType, type, data }, pipes.concat(paramHandlers)); }; await Promise.all(paramsOptions.map(resolveParamValue)); }; return paramsOptions.length ? handlerFn : null; } async getParamValue(value, { metaType, type, data }, handlers) { return (0, utils_1.isEmpty)(handlers) ? value : this.handlersConsumer.apply(value, { metaType, type, data }, handlers); } async transformToResult(resultOrDeferred) { if ((0, rxjs_1.isObservable)(resultOrDeferred)) { return (0, rxjs_1.lastValueFrom)(resultOrDeferred); } return resultOrDeferred; } createAccessResourceFn(resources, instance, callback, contextType) { const accessResourceFn = async (args) => { const accessResource = await this.accessResourceConsumer.tryAccess(resources, args, instance, callback, contextType); if (!accessResource) throw new exceptions_1.ForbiddenException(access_1.FORBIDDEN_MESSAGE); }; return resources.length ? accessResourceFn : null; } registerRequestProvider(request, contextId) { this.container.registerRequestProvider(request, contextId); } } exports.ExternalContextCreator = ExternalContextCreator; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZXJuYWwtY29udGV4dC1jcmVhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvZXh0ZXJuYWwtY29udGV4dC1jcmVhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGtDQVFpQjtBQUNqQixzQ0FJbUI7QUFDbkIsa0RBQWlGO0FBQ2pGLG1EQUE4RDtBQUM5RCxxREFBb0Q7QUFDcEQseUVBQWtFO0FBRWxFLDJDQUF1RDtBQUN2RCxvQ0FBaUM7QUFFakMsOENBQWlEO0FBRWpELCtCQUFpRDtBQVlqRCxNQUFhLHNCQUFzQjtJQU0vQixZQUNxQiw0QkFBMEQsRUFDMUQsc0JBQThDLEVBQzlDLDBCQUFzRCxFQUN0RCxvQkFBMEMsRUFDMUMsZ0JBQWtDLEVBQ2xDLHNCQUE4QyxFQUM5QyxnQkFBa0MsRUFDbEMscUJBQXFEO1FBUHJELGlDQUE0QixHQUE1Qiw0QkFBNEIsQ0FBOEI7UUFDMUQsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQUM5QywrQkFBMEIsR0FBMUIsMEJBQTBCLENBQTRCO1FBQ3RELHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBQzlDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUFnQztRQWJ6RCxpQkFBWSxHQUFHLElBQUksNEJBQVksRUFBRSxDQUFDO1FBQ2xDLHVCQUFrQixHQUFHLElBQUksbUNBQWtCLEVBQUUsQ0FBQztRQUM5QywyQkFBc0IsR0FBRyxJQUFJLGlEQUFzQixFQUFvQyxDQUFDO0lBYXpHLENBQUM7SUFFRCxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQXVCO1FBQ3hDLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSxxQ0FBNEIsQ0FDakUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxpQkFBaUIsQ0FDekMs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QUU7WUFDM0MsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUM5RCxTQUFTLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFFdEQsSUFBSSxDQUFDLGNBQWM7Z0JBQUUsTUFBTSxJQUFJLCtCQUFrQixDQUFDLDBCQUFpQixDQUFDLENBQUM7UUFFekUsQ0FBQyxDQUFDO1FBQ0YsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3RELENBQUM7SUFFTSx1QkFBdUIsQ0FBVSxPQUFVLEVBQUUsU0FBb0I7UUFDcEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBSSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDbEUsQ0FBQztDQUNKO0FBelFELHdEQXlRQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgRXh0ZXJuYWxFeGNlcHRpb25GaWx0ZXJDb250ZXh0LFxuICAgIFNUQVRJQ19DT05URVhULFxuICAgIENvbnRhaW5lcklvQyxcbiAgICBDb250ZXh0SWQsXG4gICAgTW9kdWxlc0NvbnRhaW5lcixcbiAgICBIYW5kbGVyc0NvbnN1bWVyLFxuICAgIEhhbmRsZXJzQ29udGV4dENyZWF0b3Jcbn0gZnJvbSAnLi4vY29yZSc7XG5pbXBvcnQge1xuICAgIEZPUkJJRERFTl9NRVNTQUdFLFxuICAgIEFjY2Vzc1Jlc291cmNlQ29uc3VtZXIsXG4gICAgQWNjZXNzUmVzb3VyY2VDb250ZXh0Q3JlYXRvclxufSBmcm9tICcuLi9hY2Nlc3MnO1xuaW1wb3J0IHtJbnRlcmNlcHRvcnNDb25zdW1lciwgSW50ZXJjZXB0b3JzQ29udGV4dENyZWF0b3J9IGZyb20gJy4uL2ludGVyY2VwdG9ycyc7XG5pbXBvcnQge0NvbnRleHRVdGlscywgUGFyYW1Qcm9wZXJ0aWVzfSBmcm9tICcuL2NvbnRleHQtdXRpbHMnO1xuaW1wb3J0IHtFeHRlcm5hbEVycm9yUHJveHl9IGZyb20gJy4vZXh0ZXJuYWwtcHJveHknO1xuaW1wb3J0IHtIYW5kbGVyTWV0YWRhdGFTdG9yYWdlfSBmcm9tICcuL2hhbmRsZXItbWV0YWRhdGEtc3RvcmFnZSc7XG5pbXBvcnQge0V4dGVybmFsSGFuZGxlck1ldGFkYXRhSW50ZXJmYWNlLCBIYW5kbGVyVHJhbnNmb3JtfSBmcm9tIFwiLi4vY29udHJhY3RzXCI7XG5pbXBvcnQge0NVU1RPTV9ST1VURV9BR1JTX01FVEFEQVRBfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7aXNFbXB0eX0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQge1BhcmFtRGF0YX0gZnJvbSBcIi4uL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7Rm9yYmlkZGVuRXhjZXB0aW9ufSBmcm9tIFwiLi4vZXhjZXB0aW9uc1wiO1xuaW1wb3J0IHtDb250ZXh0VHlwZSwgQ29udHJvbGxlclR5cGUsIFBhcmFtc01ldGFkYXRhVHlwZX0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge2lzT2JzZXJ2YWJsZSwgbGFzdFZhbHVlRnJvbX0gZnJvbSBcInJ4anNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBQYXJhbXNGYWN0b3J5IHtcbiAgICBleGNoYW5nZUtleUZvclZhbHVlKHR5cGU6IG51bWJlciwgZGF0YTogUGFyYW1EYXRhLCBhcmdzOiBhbnkpOiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0ZXJuYWxDb250ZXh0T3B0aW9ucyB7XG4gICAgcmVzb3VyY2VzPzogYm9vbGVhbjtcbiAgICBpbnRlcmNlcHRvcnM/OiBib29sZWFuO1xuICAgIGZpbHRlcnM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgRXh0ZXJuYWxDb250ZXh0Q3JlYXRvciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjb250ZXh0VXRpbHMgPSBuZXcgQ29udGV4dFV0aWxzKCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBleHRlcm5hbEVycm9yUHJveHkgPSBuZXcgRXh0ZXJuYWxFcnJvclByb3h5KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBoYW5kbGVyTWV0YWRhdGFTdG9yYWdlID0gbmV3IEhhbmRsZXJNZXRhZGF0YVN0b3JhZ2U8RXh0ZXJuYWxIYW5kbGVyTWV0YWRhdGFJbnRlcmZhY2U+KCk7XG4gICAgcHJpdmF0ZSBjb250YWluZXI6IENvbnRhaW5lcklvQztcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGFjY2Vzc1Jlc291cmNlQ29udGV4dENyZWF0b3I6IEFjY2Vzc1Jlc291cmNlQ29udGV4dENyZWF0b3IsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgYWNjZXNzUmVzb3VyY2VDb25zdW1lcjogQWNjZXNzUmVzb3VyY2VDb25zdW1lcixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBpbnRlcmNlcHRvcnNDb250ZXh0Q3JlYXRvcjogSW50ZXJjZXB0b3JzQ29udGV4dENyZWF0b3IsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgaW50ZXJjZXB0b3JzQ29uc3VtZXI6IEludGVyY2VwdG9yc0NvbnN1bWVyLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IG1vZHVsZXNDb250YWluZXI6IE1vZHVsZXNDb250YWluZXIsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgaGFuZGxlcnNDb250ZXh0Q3JlYXRvcjogSGFuZGxlcnNDb250ZXh0Q3JlYXRvcixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBoYW5kbGVyc0NvbnN1bWVyOiBIYW5kbGVyc0NvbnN1bWVyLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGZpbHRlcnNDb250ZXh0Q3JlYXRvcjogRXh0ZXJuYWxFeGNlcHRpb25GaWx0ZXJDb250ZXh0LFxuICAgICkge1xuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tQ29udGFpbmVyKGNvbnRhaW5lcjogQ29udGFpbmVySW9DKTogRXh0ZXJuYWxDb250ZXh0Q3JlYXRvciB7XG4gICAgICAgIGNvbnN0IGFjY2Vzc1Jlc291cmNlQ29udGV4dENyZWF0b3IgPSBuZXcgQWNjZXNzUmVzb3VyY2VDb250ZXh0Q3JlYXRvcihcbiAgICAgICAgICAgIGNvbnRhaW5lciwgY29udGFpbmVyLmFwcGxpY2F0aW9uQ29uZmlnXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGFjY2Vzc1Jlc291cmNlQ29uc3VtZXIgPSBuZXcgQWNjZXNzUmVzb3VyY2VDb25zdW1lcigpO1xuICAgICAgICBjb25zdCBpbnRlcmNlcHRvcnNDb250ZXh0Q3JlYXRvciA9IG5ldyBJbnRlcmNlcHRvcnNDb250ZXh0Q3JlYXRvcihcbiAgICAgICAgICAgIGNvbnRhaW5lciwgY29udGFpbmVyLmFwcGxpY2F0aW9uQ29uZmlnXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGludGVyY2VwdG9yc0NvbnN1bWVyID0gbmV3IEludGVyY2VwdG9yc0NvbnN1bWVyKCk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJzQ29udGV4dENyZWF0b3IgPSBuZXcgSGFuZGxlcnNDb250ZXh0Q3JlYXRvcihcbiAgICAgICAgICAgIGNvbnRhaW5lciwgY29udGFpbmVyLmFwcGxpY2F0aW9uQ29uZmlnXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJzQ29uc3VtZXIgPSBuZXcgSGFuZGxlcnNDb25zdW1lcigpO1xuICAgICAgICBjb25zdCBmaWx0ZXJzQ29udGV4dENyZWF0b3IgPSBuZXcgRXh0ZXJuYWxFeGNlcHRpb25GaWx0ZXJDb250ZXh0KFxuICAgICAgICAgICAgY29udGFpbmVyLCBjb250YWluZXIuYXBwbGljYXRpb25Db25maWcsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgZXh0ZXJuYWxDb250ZXh0Q3JlYXRvciA9IG5ldyBFeHRlcm5hbENvbnRleHRDcmVhdG9yKFxuICAgICAgICAgICAgYWNjZXNzUmVzb3VyY2VDb250ZXh0Q3JlYXRvcixcbiAgICAgICAgICAgIGFjY2Vzc1Jlc291cmNlQ29uc3VtZXIsXG4gICAgICAgICAgICBpbnRlcmNlcHRvcnNDb250ZXh0Q3JlYXRvcixcbiAgICAgICAgICAgIGludGVyY2VwdG9yc0NvbnN1bWVyLFxuICAgICAgICAgICAgY29udGFpbmVyLmdldE1vZHVsZXMoKSxcbiAgICAgICAgICAgIGhhbmRsZXJzQ29udGV4dENyZWF0b3IsXG4gICAgICAgICAgICBoYW5kbGVyc0NvbnN1bWVyLFxuICAgICAgICAgICAgZmlsdGVyc0NvbnRleHRDcmVhdG9yLFxuICAgICAgICApO1xuICAgICAgICBleHRlcm5hbENvbnRleHRDcmVhdG9yLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgcmV0dXJuIGV4dGVybmFsQ29udGV4dENyZWF0b3I7XG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZTxQIGV4dGVuZHMgUGFyYW1zTWV0YWRhdGFUeXBlID0gUGFyYW1zTWV0YWRhdGFUeXBlLCBUIGV4dGVuZHMgc3RyaW5nID0gQ29udGV4dFR5cGU+KFxuICAgICAgICBpbnN0YW5jZTogQ29udHJvbGxlclR5cGUsXG4gICAgICAgIGNhbGxiYWNrOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duLFxuICAgICAgICBtZXRob2ROYW1lOiBzdHJpbmcsXG4gICAgICAgIG1ldGFkYXRhS2V5Pzogc3RyaW5nLFxuICAgICAgICBwYXJhbXNGYWN0b3J5PzogUGFyYW1zRmFjdG9yeSxcbiAgICAgICAgY29udGV4dElkID0gU1RBVElDX0NPTlRFWFQsXG4gICAgICAgIGlucXVpcmVySWQ/OiBzdHJpbmcsXG4gICAgICAgIG9wdGlvbnM6IEV4dGVybmFsQ29udGV4dE9wdGlvbnMgPSB7XG4gICAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRydWUsXG4gICAgICAgICAgICByZXNvdXJjZXM6IHRydWUsXG4gICAgICAgICAgICBmaWx0ZXJzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjb250ZXh0VHlwZTogVCA9ICdodHRwJyBhcyBULFxuICAgICkge1xuICAgICAgICBjb25zdCBtb2R1bGUgPSB0aGlzLmdldENvbnRleHRNb2R1bGVLZXkoaW5zdGFuY2UuY29uc3RydWN0b3IpO1xuICAgICAgICBjb25zdCB7YXJnc0xlbmd0aCwgcGFyYW1UeXBlcywgZ2V0UGFyYW1zTWV0YWRhdGF9ID0gdGhpcy5nZXRNZXRhZGF0YTxQLCBUPihcbiAgICAgICAgICAgIGluc3RhbmNlLCBtZXRob2ROYW1lLCBtZXRhZGF0YUtleSwgcGFyYW1zRmFjdG9yeSwgY29udGV4dFR5cGVcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgaGFuZGxlcnMgPSB0aGlzLmhhbmRsZXJzQ29udGV4dENyZWF0b3IuY3JlYXRlKFxuICAgICAgICAgICAgaW5zdGFuY2UsIGNhbGxiYWNrLCBtb2R1bGUsIGNvbnRleHRJZCwgaW5xdWlyZXJJZFxuICAgICAgICApO1xuICAgICAgICBjb25zdCByZXNvdXJjZXMgPSB0aGlzLmFjY2Vzc1Jlc291cmNlQ29udGV4dENyZWF0b3IuY3JlYXRlKFxuICAgICAgICAgICAgaW5zdGFuY2UsIGNhbGxiYWNrLCBtb2R1bGUsIGNvbnRleHRJZCwgaW5xdWlyZXJJZFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBleGNlcHRpb25GaWx0ZXIgPSB0aGlzLmZpbHRlcnNDb250ZXh0Q3JlYXRvci5jcmVhdGUoXG4gICAgICAgICAgICBpbnN0YW5jZSwgY2FsbGJhY2ssIG1vZHVsZSwgY29udGV4dElkLCBpbnF1aXJlcklkXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGludGVyY2VwdG9ycyA9IG9wdGlvbnMuaW50ZXJjZXB0b3JzXG4gICAgICAgICAgICA/IHRoaXMuaW50ZXJjZXB0b3JzQ29udGV4dENyZWF0b3IuY3JlYXRlKFxuICAgICAgICAgICAgICAgIGluc3RhbmNlLCBjYWxsYmFjaywgbW9kdWxlLCBjb250ZXh0SWQsIGlucXVpcmVySWRcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIDogW107XG5cbiAgICAgICAgY29uc3QgcGFyYW1zTWV0YWRhdGEgPSBnZXRQYXJhbXNNZXRhZGF0YShtb2R1bGUsIGNvbnRleHRJZCwgaW5xdWlyZXJJZCk7XG4gICAgICAgIGNvbnN0IHBhcmFtc09wdGlvbnMgPSBwYXJhbXNNZXRhZGF0YVxuICAgICAgICAgICAgPyB0aGlzLmNvbnRleHRVdGlscy5tZXJnZVBhcmFtc01ldGFUeXBlcyhwYXJhbXNNZXRhZGF0YSwgcGFyYW1UeXBlcykgOiBbXTtcblxuICAgICAgICBjb25zdCBmbkFjY2Vzc1Jlc291cmNlID0gb3B0aW9ucy5yZXNvdXJjZXNcbiAgICAgICAgICAgID8gdGhpcy5jcmVhdGVBY2Nlc3NSZXNvdXJjZUZuKHJlc291cmNlcywgaW5zdGFuY2UsIGNhbGxiYWNrLCBjb250ZXh0VHlwZSkgOiBudWxsO1xuXG4gICAgICAgIGNvbnN0IGZuQXBwbHlIYW5kbGVycyA9IHRoaXMuY3JlYXRlSGFuZGxlcnNGbihoYW5kbGVycywgcGFyYW1zT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSAoaW5pdGlhbEFyZ3M6IHVua25vd25bXSwgLi4uYXJnczogdW5rbm93bltdKSA9PlxuICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChmbkFwcGx5SGFuZGxlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZm5BcHBseUhhbmRsZXJzKGluaXRpYWxBcmdzLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGluc3RhbmNlLCBpbml0aWFsQXJncyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseShpbnN0YW5jZSwgYXJncyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGFzeW5jICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5pdGlhbEFyZ3MgPSB0aGlzLmNvbnRleHRVdGlscy5jcmVhdGVOdWxsQXJyYXkoYXJnc0xlbmd0aCk7XG4gICAgICAgICAgICBmbkFjY2Vzc1Jlc291cmNlICYmIChhd2FpdCBmbkFjY2Vzc1Jlc291cmNlKGFyZ3MpKTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5pbnRlcmNlcHRvcnNDb25zdW1lci5pbnRlcmNlcHQoXG4gICAgICAgICAgICAgICAgaW50ZXJjZXB0b3JzLCBhcmdzLCBpbnN0YW5jZSwgY2FsbGJhY2ssIGhhbmRsZXIoaW5pdGlhbEFyZ3MsIC4uLmFyZ3MpLCBjb250ZXh0VHlwZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1Ub1Jlc3VsdChyZXN1bHQpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5maWx0ZXJzXG4gICAgICAgICAgICA/IHRoaXMuZXh0ZXJuYWxFcnJvclByb3h5LmNyZWF0ZVByb3h5KFxuICAgICAgICAgICAgICAgIHRhcmdldCwgZXhjZXB0aW9uRmlsdGVyLCBjb250ZXh0VHlwZSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIDogdGFyZ2V0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRNZXRhZGF0YTxULCBDIGV4dGVuZHMgc3RyaW5nID0gQ29udGV4dFR5cGU+KFxuICAgICAgICBpbnN0YW5jZTogQ29udHJvbGxlclR5cGUsXG4gICAgICAgIG1ldGhvZE5hbWU6IHN0cmluZyxcbiAgICAgICAgbWV0YWRhdGFLZXk/OiBzdHJpbmcsXG4gICAgICAgIHBhcmFtc0ZhY3Rvcnk/OiBQYXJhbXNGYWN0b3J5LFxuICAgICAgICBjb250ZXh0VHlwZT86IEMsXG4gICAgKTogRXh0ZXJuYWxIYW5kbGVyTWV0YWRhdGFJbnRlcmZhY2Uge1xuICAgICAgICBjb25zdCBjYWNoZU1ldGFkYXRhID0gdGhpcy5oYW5kbGVyTWV0YWRhdGFTdG9yYWdlLmdldChpbnN0YW5jZSwgbWV0aG9kTmFtZSk7XG4gICAgICAgIGlmIChjYWNoZU1ldGFkYXRhKSByZXR1cm4gY2FjaGVNZXRhZGF0YTtcblxuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY29udGV4dFV0aWxzLnJlZmxlY3RDYWxsYmFja01ldGFkYXRhPFQ+KFxuICAgICAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgICAgICBtZXRob2ROYW1lLFxuICAgICAgICAgICAgbWV0YWRhdGFLZXkgfHwgJycsXG4gICAgICAgICkgfHwge307XG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhtZXRhZGF0YSk7XG4gICAgICAgIGNvbnN0IGFyZ3NMZW5ndGggPSB0aGlzLmNvbnRleHRVdGlscy5nZXRBcmd1bWVudHNMZW5ndGgoa2V5cywgbWV0YWRhdGEpO1xuICAgICAgICBjb25zdCBwYXJhbVR5cGVzID0gdGhpcy5jb250ZXh0VXRpbHMucmVmbGVjdENhbGxiYWNrUGFyYW1UeXBlcyhpbnN0YW5jZSwgbWV0aG9kTmFtZSk7XG4gICAgICAgIGNvbnN0IGNvbnRleHRGYWN0b3J5ID0gdGhpcy5jb250ZXh0VXRpbHMuZ2V0Q29udGV4dEZhY3Rvcnk8Qz4oY29udGV4dFR5cGUsIGluc3RhbmNlLCBpbnN0YW5jZVttZXRob2ROYW1lXSk7XG4gICAgICAgIGNvbnN0IGdldFBhcmFtc01ldGFkYXRhID0gKG1vZHVsZUtleTogc3RyaW5nLCBjb250ZXh0SWQgPSBTVEFUSUNfQ09OVEVYVCwgaW5xdWlyZXJJZD86IHN0cmluZykgPT5cbiAgICAgICAgICAgIHBhcmFtc0ZhY3RvcnlcbiAgICAgICAgICAgICAgICA/IHRoaXMuZXhjaGFuZ2VLZXlzRm9yVmFsdWVzKFxuICAgICAgICAgICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlS2V5LFxuICAgICAgICAgICAgICAgICAgICBwYXJhbXNGYWN0b3J5LFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgICAgICAgICAgICAgIGlucXVpcmVySWQsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRGYWN0b3J5LFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA6IG51bGw7XG5cbiAgICAgICAgY29uc3QgaGFuZGxlck1ldGFkYXRhOiBFeHRlcm5hbEhhbmRsZXJNZXRhZGF0YUludGVyZmFjZSA9IHtcbiAgICAgICAgICAgIGFyZ3NMZW5ndGgsXG4gICAgICAgICAgICBwYXJhbVR5cGVzLFxuICAgICAgICAgICAgZ2V0UGFyYW1zTWV0YWRhdGEsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlck1ldGFkYXRhU3RvcmFnZS5zZXQoaW5zdGFuY2UsIG1ldGhvZE5hbWUsIGhhbmRsZXJNZXRhZGF0YSk7XG4gICAgICAgIHJldHVybiBoYW5kbGVyTWV0YWRhdGE7XG4gICAgfVxuXG4gICAgcHVibGljIGdldENvbnRleHRNb2R1bGVLZXkobW9kdWxlQ3RvcjogRnVuY3Rpb24gfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBlbXB0eU1vZHVsZUtleSA9ICcnO1xuICAgICAgICBpZiAoIW1vZHVsZUN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlbXB0eU1vZHVsZUtleTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtb2R1bGVDb250YWluZXJFbnRyaWVzID0gdGhpcy5tb2R1bGVzQ29udGFpbmVyLmVudHJpZXMoKTtcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCBtb2R1bGVSZWZdIG9mIG1vZHVsZUNvbnRhaW5lckVudHJpZXMpIHtcbiAgICAgICAgICAgIGlmIChtb2R1bGVSZWYuaGFzUHJvdmlkZXIobW9kdWxlQ3RvcikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbXB0eU1vZHVsZUtleTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZXhjaGFuZ2VLZXlzRm9yVmFsdWVzPFQgPSBhbnk+KFxuICAgICAgICBrZXlzOiBzdHJpbmdbXSxcbiAgICAgICAgbWV0YWRhdGE6IFQsXG4gICAgICAgIG1vZHVsZUNvbnRleHQ6IHN0cmluZyxcbiAgICAgICAgcGFyYW1zRmFjdG9yeTogUGFyYW1zRmFjdG9yeSxcbiAgICAgICAgY29udGV4dElkID0gU1RBVElDX0NPTlRFWFQsXG4gICAgICAgIGlucXVpcmVySWQ/OiBzdHJpbmcsXG4gICAgICAgIGNvbnRleHRGYWN0b3J5ID0gdGhpcy5jb250ZXh0VXRpbHMuZ2V0Q29udGV4dEZhY3RvcnkoJ2h0dHAnKSxcbiAgICApOiBQYXJhbVByb3BlcnRpZXNbXSB7XG4gICAgICAgIHRoaXMuaGFuZGxlcnNDb250ZXh0Q3JlYXRvci5zZXRNb2R1bGVDb250ZXh0KG1vZHVsZUNvbnRleHQpO1xuXG4gICAgICAgIHJldHVybiBrZXlzLm1hcChrZXkgPT4ge1xuICAgICAgICAgICAgY29uc3Qge2luZGV4LCBkYXRhLCBoYW5kbGVyczogaGFuZGxlcnNDb2xsZWN0aW9ufSA9IG1ldGFkYXRhW2tleV07XG4gICAgICAgICAgICBjb25zdCBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnNDb250ZXh0Q3JlYXRvci5jcmVhdGVDb25jcmV0ZUNvbnRleHQoXG4gICAgICAgICAgICAgICAgaGFuZGxlcnNDb2xsZWN0aW9uLFxuICAgICAgICAgICAgICAgIGNvbnRleHRJZCxcbiAgICAgICAgICAgICAgICBpbnF1aXJlcklkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLmNvbnRleHRVdGlscy5tYXBQYXJhbVR5cGUoa2V5KTtcblxuICAgICAgICAgICAgaWYgKGtleS5pbmNsdWRlcyhDVVNUT01fUk9VVEVfQUdSU19NRVRBREFUQSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7ZmFjdG9yeX0gPSBtZXRhZGF0YVtrZXldO1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1c3RvbUV4dHJhY3RWYWx1ZSA9IHRoaXMuY29udGV4dFV0aWxzLmdldEN1c3RvbUZhY3RvcnkoXG4gICAgICAgICAgICAgICAgICAgIGZhY3RvcnksXG4gICAgICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRGYWN0b3J5LFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtpbmRleCwgZXh0cmFjdFZhbHVlOiBjdXN0b21FeHRyYWN0VmFsdWUsIHR5cGUsIGRhdGEsIGhhbmRsZXJzfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWNUeXBlID0gTnVtYmVyKHR5cGUpO1xuICAgICAgICAgICAgY29uc3QgZXh0cmFjdFZhbHVlID0gKC4uLmFyZ3M6IHVua25vd25bXSkgPT5cbiAgICAgICAgICAgICAgICBwYXJhbXNGYWN0b3J5LmV4Y2hhbmdlS2V5Rm9yVmFsdWUobnVtZXJpY1R5cGUsIGRhdGEsIGFyZ3MpO1xuXG4gICAgICAgICAgICByZXR1cm4ge2luZGV4LCBleHRyYWN0VmFsdWUsIHR5cGU6IG51bWVyaWNUeXBlLCBkYXRhLCBoYW5kbGVyc307XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVIYW5kbGVyc0ZuKHBpcGVzOiBIYW5kbGVyVHJhbnNmb3JtW10sIHBhcmFtc09wdGlvbnM6IChQYXJhbVByb3BlcnRpZXMgJiB7IG1ldGFUeXBlPzogdW5rbm93biB9KVtdKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJGbiA9IGFzeW5jIChhcmdzOiB1bmtub3duW10sIC4uLnBhcmFtczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlUGFyYW1WYWx1ZSA9IGFzeW5jIChwYXJhbTogUGFyYW1Qcm9wZXJ0aWVzICYgeyBtZXRhVHlwZT86IHVua25vd24gfSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIGV4dHJhY3RWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgbWV0YVR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZXJzOiBwYXJhbUhhbmRsZXJzLFxuICAgICAgICAgICAgICAgIH0gPSBwYXJhbTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGV4dHJhY3RWYWx1ZSguLi5wYXJhbXMpO1xuXG4gICAgICAgICAgICAgICAgYXJnc1tpbmRleF0gPSBhd2FpdCB0aGlzLmdldFBhcmFtVmFsdWUoXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB7bWV0YVR5cGUsIHR5cGUsIGRhdGF9LFxuICAgICAgICAgICAgICAgICAgICBwaXBlcy5jb25jYXQocGFyYW1IYW5kbGVycyksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChwYXJhbXNPcHRpb25zLm1hcChyZXNvbHZlUGFyYW1WYWx1ZSkpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcGFyYW1zT3B0aW9ucy5sZW5ndGggPyBoYW5kbGVyRm4gOiBudWxsO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRQYXJhbVZhbHVlPFQ+KFxuICAgICAgICB2YWx1ZTogVCxcbiAgICAgICAge21ldGFUeXBlLCB0eXBlLCBkYXRhfTogeyBtZXRhVHlwZTogYW55OyB0eXBlOiBhbnk7IGRhdGE6IGFueSB9LFxuICAgICAgICBoYW5kbGVyczogSGFuZGxlclRyYW5zZm9ybVtdKTogUHJvbWlzZTxhbnk+IHtcblxuICAgICAgICByZXR1cm4gaXNFbXB0eShoYW5kbGVycylcbiAgICAgICAgICAgID8gdmFsdWUgOiB0aGlzLmhhbmRsZXJzQ29uc3VtZXIuYXBwbHkodmFsdWUsIHttZXRhVHlwZSwgdHlwZSwgZGF0YX0sIGhhbmRsZXJzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtVG9SZXN1bHQocmVzdWx0T3JEZWZlcnJlZDogYW55KSB7XG4gICAgICAgIGlmKGlzT2JzZXJ2YWJsZShyZXN1bHRPckRlZmVycmVkKSkge1xuICAgICAgICAgICAgcmV0dXJuIGxhc3RWYWx1ZUZyb20ocmVzdWx0T3JEZWZlcnJlZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdE9yRGVmZXJyZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZUFjY2Vzc1Jlc291cmNlRm48VCBleHRlbmRzIHN0cmluZyA9IENvbnRleHRUeXBlPihcbiAgICAgICAgcmVzb3VyY2VzOiBhbnlbXSwgaW5zdGFuY2U6IENvbnRyb2xsZXJUeXBlLCBjYWxsYmFjazogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnksXG4gICAgICAgIGNvbnRleHRUeXBlPzogVCk6IEZ1bmN0aW9uIHwgbnVsbCB7XG5cbiAgICAgICAgY29uc3QgYWNjZXNzUmVzb3VyY2VGbiA9IGFzeW5jIChhcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWNjZXNzUmVzb3VyY2UgPSBhd2FpdCB0aGlzLmFjY2Vzc1Jlc291cmNlQ29uc3VtZXIudHJ5QWNjZXNzPFQ+KFxuICAgICAgICAgICAgICAgIHJlc291cmNlcywgYXJncywgaW5zdGFuY2UsIGNhbGxiYWNrLCBjb250ZXh0VHlwZSk7XG5cbiAgICAgICAgICAgIGlmICghYWNjZXNzUmVzb3VyY2UpIHRocm93IG5ldyBGb3JiaWRkZW5FeGNlcHRpb24oRk9SQklEREVOX01FU1NBR0UpO1xuXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiByZXNvdXJjZXMubGVuZ3RoID8gYWNjZXNzUmVzb3VyY2VGbiA6IG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZ2lzdGVyUmVxdWVzdFByb3ZpZGVyPFQgPSBhbnk+KHJlcXVlc3Q6IFQsIGNvbnRleHRJZDogQ29udGV4dElkKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnJlZ2lzdGVyUmVxdWVzdFByb3ZpZGVyPFQ+KHJlcXVlc3QsIGNvbnRleHRJZCk7XG4gICAgfVxufVxuIl19