UNPKG

@tsclean/core

Version:

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

405 lines 77.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Injector = void 0; const iterare_1 = require("iterare"); const runtime_1 = require("../../errors/exceptions/runtime"); const undefined_dependency_1 = require("../../errors/exceptions/undefined-dependency"); const unknown_dependencies_1 = require("../../errors/exceptions/unknown-dependencies"); const constants_1 = require("./constants"); const inquirer_1 = require("./inquirer"); const instance_wrapper_1 = require("./instance-wrapper"); const utils_1 = require("../../utils"); const helpers_1 = require("../../helpers"); const services_1 = require("../../services"); class Injector { constructor(options) { this.options = options; this.logger = new services_1.Logger('InjectorLogger'); } loadPrototype({ token }, collection, contextId = constants_1.STATIC_CONTEXT) { if (!collection) { return; } const target = collection.get(token); const instance = target.createPrototype(contextId); if (instance) { const wrapper = new instance_wrapper_1.InstanceWrapper(Object.assign(Object.assign({}, target), { instance })); collection.set(token, wrapper); } } async loadInstance(wrapper, collection, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) { const inquirerId = Injector.getInquirerId(inquirer); const instanceHost = wrapper.getInstanceByContextId(contextId, inquirerId); if (instanceHost.isPending) { return instanceHost.donePromise; } const done = this.applyDoneHook(instanceHost); const token = wrapper.token || wrapper.name; const { inject } = wrapper; const targetWrapper = collection.get(token); if ((0, utils_1.isUndefined)(targetWrapper)) { throw new runtime_1.RuntimeException(); } if (instanceHost.isResolved) { return done(); } const callback = async (instances) => { const properties = await this.resolveProperties(wrapper, moduleRef, inject, contextId, wrapper, inquirer); const instance = await this.instantiateClass(instances, wrapper, targetWrapper, contextId, inquirer); this.applyProperties(instance, properties); done(); }; await this.resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId, wrapper, inquirer); } async loadMiddleware(wrapper, collection, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) { const { metaType, token } = wrapper; const targetWrapper = collection.get(token); if (!(0, utils_1.isUndefined)(targetWrapper.instance)) { return; } targetWrapper.instance = Object.create(metaType.prototype); await this.loadInstance(wrapper, collection, moduleRef, contextId, inquirer || wrapper); } async loadController(wrapper, moduleRef, contextId = constants_1.STATIC_CONTEXT) { const controllers = moduleRef.controllers; await this.loadInstance(wrapper, controllers, moduleRef, contextId, wrapper); await this.loadEnhancersPerContext(wrapper, contextId, wrapper); } async loadInjectable(wrapper, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) { const injectables = moduleRef.injectables; await this.loadInstance(wrapper, injectables, moduleRef, contextId, inquirer); } async loadProvider(wrapper, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) { const providers = moduleRef.providers; await this.loadInstance(wrapper, providers, moduleRef, contextId, inquirer); await this.loadEnhancersPerContext(wrapper, contextId, wrapper); } applyDoneHook(wrapper) { let done; wrapper.donePromise = new Promise((resolve, reject) => { done = resolve; }); wrapper.isPending = true; return done; } async resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId = constants_1.STATIC_CONTEXT, inquirer, parentInquirer) { let inquirerId = Injector.getInquirerId(inquirer); const metadata = wrapper.getCtorMetadata(); if (metadata && contextId !== constants_1.STATIC_CONTEXT) { const deps = await this.loadCtorMetadata(metadata, contextId, inquirer, parentInquirer); return callback(deps); } const dependencies = (0, utils_1.isNil)(inject) ? this.reflectConstructorParams(wrapper.metaType) : inject; const optionalDependenciesIds = (0, utils_1.isNil)(inject) ? this.reflectOptionalParams(wrapper.metaType) : []; let isResolved = true; const resolveParam = async (param, index) => { try { if (Injector.isInquirer(param, parentInquirer)) { return parentInquirer && parentInquirer.instance; } if ((inquirer === null || inquirer === void 0 ? void 0 : inquirer.isTransient) && parentInquirer) { inquirer = parentInquirer; inquirerId = Injector.getInquirerId(parentInquirer); } const paramWrapper = await this.resolveSingleParam(wrapper, param, { index, dependencies }, moduleRef, contextId, inquirer, index); const instanceHost = paramWrapper.getInstanceByContextId(contextId, inquirerId); if (!instanceHost.isResolved && !paramWrapper.forwardRef) { isResolved = false; } return instanceHost === null || instanceHost === void 0 ? void 0 : instanceHost.instance; } catch (err) { const isOptional = optionalDependenciesIds.includes(index); if (!isOptional) { throw err; } return undefined; } }; const instances = await Promise.all(dependencies.map(resolveParam)); isResolved && (await callback(instances)); } reflectConstructorParams(type) { const paramtypes = Reflect.getMetadata(helpers_1.PARAMTYPES_METADATA, type) || []; const selfParams = this.reflectSelfParams(type); selfParams.forEach(({ index, param }) => (paramtypes[index] = param)); return paramtypes; } reflectOptionalParams(type) { return Reflect.getMetadata(helpers_1.OPTIONAL_DEPS_METADATA, type) || []; } reflectSelfParams(type) { return Reflect.getMetadata(helpers_1.SELF_DECLARED_DEPS_METADATA, type) || []; } async resolveSingleParam(wrapper, param, dependencyContext, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) { if ((0, utils_1.isUndefined)(param)) { throw new undefined_dependency_1.UndefinedDependencyException(wrapper.name, dependencyContext, moduleRef); } const token = this.resolveParamToken(wrapper, param); return this.resolveComponentInstance(moduleRef, token, dependencyContext, wrapper, contextId, inquirer, keyOrIndex); } resolveParamToken(wrapper, param) { if (!param.forwardRef) { return param; } wrapper.forwardRef = true; return param.forwardRef(); } async resolveComponentInstance(moduleRef, token, dependencyContext, wrapper, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) { this.printResolvingDependenciesLog(token, inquirer); this.printLookingForProviderLog(token, moduleRef); const providers = moduleRef.providers; const instanceWrapper = await this.lookupComponent(providers, moduleRef, Object.assign(Object.assign({}, dependencyContext), { name: token }), wrapper, contextId, inquirer, keyOrIndex); return this.resolveComponentHost(moduleRef, instanceWrapper, contextId, inquirer); } async resolveComponentHost(moduleRef, instanceWrapper, contextId = constants_1.STATIC_CONTEXT, inquirer) { const inquirerId = Injector.getInquirerId(inquirer); const instanceHost = instanceWrapper.getInstanceByContextId(contextId, inquirerId); if (!instanceHost.isResolved && !instanceWrapper.forwardRef) { await this.loadProvider(instanceWrapper, moduleRef, contextId, inquirer); } else if (!instanceHost.isResolved && instanceWrapper.forwardRef && (contextId !== constants_1.STATIC_CONTEXT || !!inquirerId)) { /** * When circular dependency has been detected between * either request/transient providers, we have to asynchronously * resolve instance host for a specific contextId or inquirer, to ensure * that eventual lazily created instance will be merged with the prototype * instantiated beforehand. */ instanceHost.donePromise && instanceHost.donePromise.then(() => this.loadProvider(instanceWrapper, moduleRef, contextId, inquirer)); } if (instanceWrapper.async) { const host = instanceWrapper.getInstanceByContextId(contextId, inquirerId); host.instance = await host.instance; instanceWrapper.setInstanceByContextId(contextId, host, inquirerId); } return instanceWrapper; } async lookupComponent(providers, moduleRef, dependencyContext, wrapper, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) { const { name } = dependencyContext; if (wrapper && wrapper.name === name) { throw new unknown_dependencies_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef); } if (providers.has(name)) { const instanceWrapper = providers.get(name); this.printFoundInModuleLog(name, moduleRef); Injector.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapper); return instanceWrapper; } return this.lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId, inquirer, keyOrIndex); } async lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) { const instanceWrapper = await this.lookupComponentInImports(moduleRef, dependencyContext.name, wrapper, [], contextId, inquirer, keyOrIndex); if ((0, utils_1.isNil)(instanceWrapper)) { throw new unknown_dependencies_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef); } return instanceWrapper; } async lookupComponentInImports(moduleRef, name, wrapper, moduleRegistry = [], contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex, isTraversing) { let instanceWrapperRef = null; const imports = moduleRef.imports || new Set(); const identity = (item) => item; let children = [...imports.values()].filter(identity); if (isTraversing) { const contextModuleExports = moduleRef.exports; children = children.filter(child => contextModuleExports.has(child.metaType)); } for (const relatedModule of children) { if (moduleRegistry.includes(relatedModule.id)) { continue; } this.printLookingForProviderLog(name, relatedModule); moduleRegistry.push(relatedModule.id); const { providers, exports } = relatedModule; if (!exports.has(name) || !providers.has(name)) { const instanceRef = await this.lookupComponentInImports(relatedModule, name, wrapper, moduleRegistry, contextId, inquirer, keyOrIndex, true); if (instanceRef) { Injector.addDependencyMetadata(keyOrIndex, wrapper, instanceRef); return instanceRef; } continue; } this.printFoundInModuleLog(name, relatedModule); instanceWrapperRef = providers.get(name); Injector.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapperRef); const inquirerId = Injector.getInquirerId(inquirer); const instanceHost = instanceWrapperRef.getInstanceByContextId(contextId, inquirerId); if (!instanceHost.isResolved && !instanceWrapperRef.forwardRef) { await this.loadProvider(instanceWrapperRef, relatedModule, contextId, wrapper); break; } } return instanceWrapperRef; } async resolveProperties(wrapper, moduleRef, inject, contextId = constants_1.STATIC_CONTEXT, inquirer, parentInquirer) { if (!(0, utils_1.isNil)(inject)) { return []; } const metadata = wrapper.getPropertiesMetadata(); if (metadata && contextId !== constants_1.STATIC_CONTEXT) { return this.loadPropertiesMetadata(metadata, contextId, inquirer); } const properties = this.reflectProperties(wrapper.metaType); const instances = await Promise.all(properties.map(async (item) => { try { const dependencyContext = { key: item.key, name: item.name }; if (Injector.isInquirer(item.name, parentInquirer)) { return parentInquirer && parentInquirer.instance; } const paramWrapper = await this.resolveSingleParam(wrapper, item.name, dependencyContext, moduleRef, contextId, inquirer, item.key); if (!paramWrapper) { return undefined; } const inquirerId = Injector.getInquirerId(inquirer); const instanceHost = paramWrapper.getInstanceByContextId(contextId, inquirerId); return instanceHost.instance; } catch (err) { if (!item.isOptional) { throw err; } return undefined; } })); return properties.map((item, index) => (Object.assign(Object.assign({}, item), { instance: instances[index] }))); } reflectProperties(type) { const properties = Reflect.getMetadata(helpers_1.PROPERTY_DEPS_METADATA, type) || []; const optionalKeys = Reflect.getMetadata(helpers_1.OPTIONAL_PROPERTY_DEPS_METADATA, type) || []; return properties.map((item) => (Object.assign(Object.assign({}, item), { name: item.type, isOptional: optionalKeys.includes(item.key) }))); } applyProperties(instance, properties) { if (!(0, utils_1.isObject)(instance)) { return undefined; } (0, iterare_1.iterate)(properties) .filter(item => !(0, utils_1.isNil)(item.instance)) .forEach(item => (instance[item.key] = item.instance)); } async instantiateClass(instances, wrapper, targetMetatype, contextId = constants_1.STATIC_CONTEXT, inquirer) { var _a, _b; const { metaType, inject } = wrapper; const inquirerId = Injector.getInquirerId(inquirer); const instanceHost = targetMetatype.getInstanceByContextId(contextId, inquirerId); const isInContext = wrapper.isStatic(contextId, inquirer) || wrapper.isInRequestScope(contextId, inquirer) || wrapper.isLazyTransient(contextId, inquirer) || wrapper.isExplicitlyRequested(contextId, inquirer); if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.preview) && !((_b = wrapper.host) === null || _b === void 0 ? void 0 : _b.initOnPreview)) { instanceHost.isResolved = true; return instanceHost.instance; } if ((0, utils_1.isNil)(inject) && isInContext) { instanceHost.instance = wrapper.forwardRef ? Object.assign(instanceHost.instance, new metaType(...instances)) : new metaType(...instances); } else if (isInContext) { const factoryReturnValue = targetMetatype.metaType(...instances); instanceHost.instance = await factoryReturnValue; } instanceHost.isResolved = true; return instanceHost.instance; } async loadPerContext(instance, moduleRef, collection, ctx, wrapper) { if (!wrapper) { const injectionToken = instance.constructor; wrapper = collection.get(injectionToken); } await this.loadInstance(wrapper, collection, moduleRef, ctx, wrapper); await this.loadEnhancersPerContext(wrapper, ctx, wrapper); const host = wrapper.getInstanceByContextId(ctx, wrapper.id); return host && host.instance; } async loadEnhancersPerContext(wrapper, ctx, inquirer) { const enhancers = wrapper.getEnhancersMetadata() || []; const loadEnhancer = (item) => { const hostModule = item.host; return this.loadInstance(item, hostModule.injectables, hostModule, ctx, inquirer); }; await Promise.all(enhancers.map(loadEnhancer)); } async loadCtorMetadata(metadata, contextId, inquirer, parentInquirer) { const hosts = await Promise.all(metadata.map(async (item) => this.resolveScopedComponentHost(item, contextId, inquirer, parentInquirer))); const inquirerId = Injector.getInquirerId(inquirer); return hosts.map(item => item.getInstanceByContextId(contextId, inquirerId).instance); } async loadPropertiesMetadata(metadata, contextId, inquirer) { const dependenciesHosts = await Promise.all(metadata.map(async ({ wrapper: item, key }) => ({ key, host: await this.resolveComponentHost(item.host, item, contextId, inquirer) }))); const inquirerId = Injector.getInquirerId(inquirer); return dependenciesHosts.map(({ key, host }) => ({ key, name: key, instance: host.getInstanceByContextId(contextId, inquirerId).instance })); } static getInquirerId(inquirer) { return inquirer && inquirer.id; } resolveScopedComponentHost(item, contextId, inquirer, parentInquirer) { return Injector.isInquirerRequest(item, parentInquirer) ? parentInquirer : this.resolveComponentHost(item.host, item, contextId, inquirer); } static isInquirerRequest(item, parentInquirer) { return item.isTransient && item.name === inquirer_1.INQUIRER && parentInquirer; } static isInquirer(param, parentInquirer) { return param === inquirer_1.INQUIRER && parentInquirer; } static addDependencyMetadata(keyOrIndex, hostWrapper, instanceWrapper) { (0, utils_1.isString)(keyOrIndex) ? hostWrapper.addPropertiesMetadata(keyOrIndex, instanceWrapper) : hostWrapper.addCtorMetadata(keyOrIndex, instanceWrapper); } static getTokenName(token) { return (0, utils_1.isFunction)(token) ? token.name : token.toString(); } printResolvingDependenciesLog(token, inquirer) { var _a; if (!Injector.isDebugMode()) { return; } const tokenName = Injector.getTokenName(token); const dependentName = (_a = inquirer === null || inquirer === void 0 ? void 0 : inquirer.name) !== null && _a !== void 0 ? _a : 'unknown'; const isAlias = dependentName === tokenName; const messageToPrint = `Resolving dependency ${utils_1.clc.cyanBright(tokenName)}${utils_1.clc.green(' in the ')}${utils_1.clc.yellow(dependentName)}${utils_1.clc.green(` provider ${isAlias ? '(alias)' : ''}`)}`; this.logger.log(messageToPrint); } printLookingForProviderLog(token, moduleRef) { var _a, _b; if (!Injector.isDebugMode()) { return; } const tokenName = Injector.getTokenName(token); const moduleRefName = (_b = (_a = moduleRef === null || moduleRef === void 0 ? void 0 : moduleRef.metaType) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown'; this.logger.log(`Looking for ${utils_1.clc.cyanBright(tokenName)}${utils_1.clc.green(' in ')}${utils_1.clc.magentaBright(moduleRefName)}`); } printFoundInModuleLog(token, moduleRef) { var _a, _b; if (!Injector.isDebugMode()) { return; } const tokenName = Injector.getTokenName(token); const moduleRefName = (_b = (_a = moduleRef === null || moduleRef === void 0 ? void 0 : moduleRef.metaType) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown'; this.logger.log(`Found ${utils_1.clc.cyanBright(tokenName)}${utils_1.clc.green(' in ')}${utils_1.clc.magentaBright(moduleRefName)}`); } static isDebugMode() { return !!process.env.NEST_DEBUG; } } exports.Injector = Injector; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9pbmplY3Rvci9pbmplY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxQ0FBaUM7QUFDakMsNkRBQWtFO0FBQ2xFLHVGQUEyRjtBQUMzRix1RkFBMkY7QUFDM0YsMkNBQTRDO0FBQzVDLHlDQUFxQztBQUNyQyx5REFLMkI7QUFHM0IsdUNBT29CO0FBQ3BCLDJDQU1zQjtBQUN0Qiw2Q0FBc0Q7QUFzQnRELE1BQWEsUUFBUTtJQUduQixZQUE4QixPQUE4QjtRQUE5QixZQUFPLEdBQVAsT0FBTyxDQUF1QjtRQUZwRCxXQUFNLEdBQWtCLElBQUksaUJBQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBRUcsQ0FBQztJQUV6RCxhQUFhLENBQ2xCLEVBQUUsS0FBSyxFQUFzQixFQUM3QixVQUFzRCxFQUN0RCxTQUFTLEdBQUcsMEJBQWM7UUFFMUIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE9BQU07UUFDUixDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNwQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ2xELElBQUksUUFBUSxFQUFFLENBQUM7WUFDYixNQUFNLE9BQU8sR0FBRyxJQUFJLGtDQUFlLGlDQUM5QixNQUFNLEtBQ1QsUUFBUSxJQUNSLENBQUE7WUFDRixVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZLENBQ3ZCLE9BQTJCLEVBQzNCLFVBQW1ELEVBQ25ELFNBQWlCLEVBQ2pCLFNBQVMsR0FBRywwQkFBYyxFQUMxQixRQUEwQjtRQUUxQixNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFD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QUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUE7SUFDakMsQ0FBQztDQUNGO0FBMXdCRCw0QkEwd0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXRlcmF0ZSB9IGZyb20gJ2l0ZXJhcmUnXG5pbXBvcnQgeyBSdW50aW1lRXhjZXB0aW9uIH0gZnJvbSAnLi4vLi4vZXJyb3JzL2V4Y2VwdGlvbnMvcnVudGltZSdcbmltcG9ydCB7IFVuZGVmaW5lZERlcGVuZGVuY3lFeGNlcHRpb24gfSBmcm9tICcuLi8uLi9lcnJvcnMvZXhjZXB0aW9ucy91bmRlZmluZWQtZGVwZW5kZW5jeSdcbmltcG9ydCB7IFVua25vd25EZXBlbmRlbmNpZXNFeGNlcHRpb24gfSBmcm9tICcuLi8uLi9lcnJvcnMvZXhjZXB0aW9ucy91bmtub3duLWRlcGVuZGVuY2llcydcbmltcG9ydCB7IFNUQVRJQ19DT05URVhUIH0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBJTlFVSVJFUiB9IGZyb20gJy4vaW5xdWlyZXInXG5pbXBvcnQge1xuICBDb250ZXh0SWQsXG4gIEluc3RhbmNlUGVyQ29udGV4dCxcbiAgSW5zdGFuY2VXcmFwcGVyLFxuICBQcm9wZXJ0eU1ldGFkYXRhXG59IGZyb20gJy4vaW5zdGFuY2Utd3JhcHBlcidcbmltcG9ydCB7IE1vZHVsZSB9IGZyb20gJy4vbW9kdWxlJ1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cydcbmltcG9ydCB7XG4gIGlzRnVuY3Rpb24sXG4gIGlzTmlsLFxuICBpc09iamVjdCxcbiAgaXNTdHJpbmcsXG4gIGlzVW5kZWZpbmVkLFxuICBjbGNcbn0gZnJvbSAnLi4vLi4vdXRpbHMnXG5pbXBvcnQge1xuICBPUFRJT05BTF9ERVBTX01FVEFEQVRBLFxuICBPUFRJT05BTF9QUk9QRVJUWV9ERVBTX01FVEFEQVRBLFxuICBQQVJBTVRZUEVTX01FVEFEQVRBLFxuICBQUk9QRVJUWV9ERVBTX01FVEFEQVRBLFxuICBTRUxGX0RFQ0xBUkVEX0RFUFNfTUVUQURBVEFcbn0gZnJvbSAnLi4vLi4vaGVscGVycydcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2VyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzJ1xuaW1wb3J0IHsgQ29udHJvbGxlclR5cGUsIEluamVjdGFibGVUeXBlLCBJbnN0YW5jZVRva2VuVHlwZSB9IGZyb20gJy4uLy4uL3R5cGVzJ1xuXG5leHBvcnQgdHlwZSBJbmplY3RvckRlcGVuZGVuY3kgPSBUeXBlPGFueT4gfCBGdW5jdGlvbiB8IHN0cmluZyB8IHN5bWJvbFxuXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnR5RGVwZW5kZW5jeSB7XG4gIGtleTogc3RyaW5nXG4gIG5hbWU6IEluamVjdG9yRGVwZW5kZW5jeVxuICBpc09wdGlvbmFsPzogYm9vbGVhblxuICBpbnN0YW5jZT86IGFueVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluamVjdG9yRGVwZW5kZW5jeUNvbnRleHQge1xuICBrZXk/OiBzdHJpbmcgfCBzeW1ib2xcblxuICBuYW1lPzogRnVuY3Rpb24gfCBzdHJpbmcgfCBzeW1ib2xcblxuICBpbmRleD86IG51bWJlclxuXG4gIGRlcGVuZGVuY2llcz86IEluamVjdG9yRGVwZW5kZW5jeVtdXG59XG5cbmV4cG9ydCBjbGFzcyBJbmplY3RvciB7XG4gIHByaXZhdGUgbG9nZ2VyOiBMb2dnZXJTZXJ2aWNlID0gbmV3IExvZ2dlcignSW5qZWN0b3JMb2dnZXInKVxuXG4gIGNvbnN0cnVjdG9yIChwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM/OiB7IHByZXZpZXc6IGJvb2xlYW4gfSkge31cblxuICBwdWJsaWMgbG9hZFByb3RvdHlwZTxUPiAoXG4gICAgeyB0b2tlbiB9OiBJbnN0YW5jZVdyYXBwZXI8VD4sXG4gICAgY29sbGVjdGlvbjogTWFwPEluc3RhbmNlVG9rZW5UeXBlLCBJbnN0YW5jZVdyYXBwZXI8VD4+LFxuICAgIGNvbnRleHRJZCA9IFNUQVRJQ19DT05URVhUXG4gICkge1xuICAgIGlmICghY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNvbnN0IHRhcmdldCA9IGNvbGxlY3Rpb24uZ2V0KHRva2VuKVxuICAgIGNvbnN0IGluc3RhbmNlID0gdGFyZ2V0LmNyZWF0ZVByb3RvdHlwZShjb250ZXh0SWQpXG4gICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICBjb25zdCB3cmFwcGVyID0gbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIC4uLnRhcmdldCxcbiAgICAgICAgaW5zdGFuY2VcbiAgICAgIH0pXG4gICAgICBjb2xsZWN0aW9uLnNldCh0b2tlbiwgd3JhcHBlcilcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbG9hZEluc3RhbmNlPFQ+IChcbiAgICB3cmFwcGVyOiBJbnN0YW5jZVdyYXBwZXI8VD4sXG4gICAgY29sbGVjdGlvbjogTWFwPEluc3RhbmNlVG9rZW5UeXBlLCBJbnN0YW5jZVdyYXBwZXI+LFxuICAgIG1vZHVsZVJlZjogTW9kdWxlLFxuICAgIGNvbnRleHRJZCA9IFNUQVRJQ19DT05URVhULFxuICAgIGlucXVpcmVyPzogSW5zdGFuY2VXcmFwcGVyXG4gICkge1xuICAgIGNvbnN0IGlucXVpcmVySWQgPSBJbmplY3Rvci5nZXRJbnF1aXJlcklkKGlucXVpcmVyKVxuICAgIGNvbnN0IGluc3RhbmNlSG9zdCA9IHdyYXBwZXIuZ2V0SW5zdGFuY2VCeUNvbnRleHRJZChjb250ZXh0SWQsIGlucXVpcmVySWQpXG4gICAgaWYgKGluc3RhbmNlSG9zdC5pc1BlbmRpbmcpIHtcbiAgICAgIHJldHVybiBpbnN0YW5jZUhvc3QuZG9uZVByb21pc2VcbiAgICB9XG4gICAgY29uc3QgZG9uZSA9IHRoaXMuYXBwbHlEb25lSG9vayhpbnN0YW5jZUhvc3QpXG4gICAgY29uc3QgdG9rZW4gPSB3cmFwcGVyLnRva2VuIHx8IHdyYXBwZXIubmFtZVxuXG4gICAgY29uc3QgeyBpbmplY3QgfSA9IHdyYXBwZXJcbiAgICBjb25zdCB0YXJnZXRXcmFwcGVyID0gY29sbGVjdGlvbi5nZXQodG9rZW4pXG4gICAgaWYgKGlzVW5kZWZpbmVkKHRhcmdldFdyYXBwZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpXG4gICAgfVxuICAgIGlmIChpbnN0YW5jZUhvc3QuaXNSZXNvbHZlZCkge1xuICAgICAgcmV0dXJuIGRvbmUoKVxuICAgIH1cbiAgICBjb25zdCBjYWxsYmFjayA9IGFzeW5jIChpbnN0YW5jZXM6IHVua25vd25bXSkgPT4ge1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGF3YWl0IHRoaXMucmVzb2x2ZVByb3BlcnRpZXMoXG4gICAgICAgIHdyYXBwZXIsXG4gICAgICAgIG1vZHVsZVJlZixcbiAgICAgICAgaW5qZWN0LFxuICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgIHdyYXBwZXIsXG4gICAgICAgIGlucXVpcmVyXG4gICAgICApXG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IHRoaXMuaW5zdGFudGlhdGVDbGFzcyhcbiAgICAgICAgaW5zdGFuY2VzLFxuICAgICAgICB3cmFwcGVyLFxuICAgICAgICB0YXJnZXRXcmFwcGVyLFxuICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgIGlucXVpcmVyXG4gICAgICApXG4gICAgICB0aGlzLmFwcGx5UHJvcGVydGllcyhpbnN0YW5jZSwgcHJvcGVydGllcylcbiAgICAgIGRvbmUoKVxuICAgIH1cbiAgICBhd2FpdCB0aGlzLnJlc29sdmVDb25zdHJ1Y3RvclBhcmFtczxUPihcbiAgICAgIHdyYXBwZXIsXG4gICAgICBtb2R1bGVSZWYsXG4gICAgICBpbmplY3QsXG4gICAgICBjYWxsYmFjayxcbiAgICAgIGNvbnRleHRJZCxcbiAgICAgIHdyYXBwZXIsXG4gICAgICBpbnF1aXJlclxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsb2FkTWlkZGxld2FyZSAoXG4gICAgd3JhcHBlcjogSW5zdGFuY2VXcmFwcGVyLFxuICAgIGNvbGxlY3Rpb246IE1hcDxJbnN0YW5jZVRva2VuVHlwZSwgSW5zdGFuY2VXcmFwcGVyPixcbiAgICBtb2R1bGVSZWY6IE1vZHVsZSxcbiAgICBjb250ZXh0SWQgPSBTVEFUSUNfQ09OVEVYVCxcbiAgICBpbnF1aXJlcj86IEluc3RhbmNlV3JhcH