UNPKG

@tsclean/core

Version:

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

165 lines 26.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StartProjectInit = exports.BootstrapInitProject = void 0; const core_1 = require("../core"); const application_config_1 = require("./application-config"); const constants_1 = require("./constants"); const errors_1 = require("../errors"); const helpers_1 = require("../helpers"); const metadata_scanner_1 = require("./metadata-scanner"); const application_1 = require("./application"); const scanner_1 = require("./scanner"); const utils_1 = require("../utils"); const services_1 = require("../services"); const inspector_1 = require("../inspector"); const application_context_1 = require("./application-context"); class BootstrapInitProject { constructor() { this.logger = new services_1.Logger(null, { timestamp: true }); this.abortOnError = true; this.autoFlushLogs = false; } async create(module, serverOrOptions, options) { const [httpServer, appOptions] = this.isHttpServer(serverOrOptions) ? [serverOrOptions, options] : [this.createHttpAdapter(), serverOrOptions]; const applicationConfig = new application_config_1.ApplicationConfig(); const container = new core_1.ContainerIoC(applicationConfig); const graphInspector = this.createGraphInspector(appOptions, container); this.setAbortOnError(serverOrOptions, options); this.registerLoggerConfiguration(appOptions); await this.initialize(module, container, graphInspector, applicationConfig, appOptions, httpServer); const instance = new application_1.Application(container, httpServer, applicationConfig, graphInspector, appOptions); const target = this.createCleanInstance(instance); return this.createAdapterProxy(target, httpServer); } async createApplicationContext(moduleCls, options) { const applicationConfig = new application_config_1.ApplicationConfig(); const container = new core_1.ContainerIoC(applicationConfig); const graphInspector = this.createGraphInspector(options, container); this.setAbortOnError(options); this.registerLoggerConfiguration(options); await this.initialize(moduleCls, container, graphInspector, applicationConfig, options); const modules = container.getModules().values(); const root = modules.next().value; const context = this.createCleanInstance(new application_context_1.ApplicationContext(container, options, root)); if (this.autoFlushLogs) { context.flushLogsOnOverride(); } return context.init(); } createCleanInstance(instance) { return this.createProxy(instance); } async initialize(module, container, graphInspector, config = new application_config_1.ApplicationConfig(), options = {}, httpServer = null) { inspector_1.UuidFactory.mode = options.snapshot ? inspector_1.UuidFactoryMode.Deterministic : inspector_1.UuidFactoryMode.Random; const injector = new core_1.Injector({ preview: options.preview }); const instanceLoader = new core_1.InstanceLoader(container, injector, graphInspector); const metadataScanner = new metadata_scanner_1.MetadataScanner(); const dependenciesScanner = new scanner_1.DependenciesScanner(container, metadataScanner, graphInspector, config); container.setHttpAdapter(httpServer); const teardown = this.abortOnError === false ? helpers_1.rethrow : undefined; await (httpServer === null || httpServer === void 0 ? void 0 : httpServer.init()); try { this.logger.log(constants_1.MESSAGES.APPLICATION_START); await errors_1.ExceptionsZone.asyncRun(async () => { await dependenciesScanner.scan(module); await instanceLoader.createInstancesOfDependencies(); dependenciesScanner.applyApplicationProviders(); }, teardown, this.autoFlushLogs); } catch (e) { this.handleInitializationError(e); } } handleInitializationError(err) { if (this.abortOnError) process.abort(); (0, helpers_1.rethrow)(err); } createProxy(target) { const proxy = this.createExceptionProxy(); return new Proxy(target, { get: proxy, set: proxy }); } createExceptionProxy() { return (receiver, prop) => { if (!(prop in receiver)) return; if ((0, utils_1.isFunction)(receiver[prop])) return this.createExceptionZone(receiver, prop); return receiver[prop]; }; } createExceptionZone(receiver, prop) { const teardown = this.abortOnError === false ? helpers_1.rethrow : undefined; return (...args) => { let result; errors_1.ExceptionsZone.run(() => { result = receiver[prop](...args); }, teardown); return result; }; } registerLoggerConfiguration(options) { if (!options) return; const { logger, bufferLogs, autoFlushLogs } = options; if (logger !== true && !(0, utils_1.isNil)(logger)) services_1.Logger.overrideLogger(logger); if (bufferLogs) services_1.Logger.attachBuffer(); this.autoFlushLogs = autoFlushLogs !== null && autoFlushLogs !== void 0 ? autoFlushLogs : true; } createHttpAdapter(httpServer) { const { ExpressAdapter } = (0, helpers_1.loadAdapter)('express', 'HTTP', () => require('../server')); return new ExpressAdapter(httpServer); } isHttpServer(serverOrOptions) { return !!(serverOrOptions && serverOrOptions.patch); } setAbortOnError(serverOrOptions, options) { this.abortOnError = this.isHttpServer(serverOrOptions) ? !(options && options.abortOnError === false) : !(serverOrOptions && serverOrOptions.abortOnError === false); } createAdapterProxy(app, adapter) { const proxy = new Proxy(app, { get: (receiver, prop) => { const mapToProxy = (result) => { return result instanceof Promise ? result.then(mapToProxy) : result instanceof application_1.Application ? proxy : result; }; if (!(prop in receiver) && prop in adapter) { return (...args) => { const result = this.createExceptionZone(adapter, prop)(...args); return mapToProxy(result); }; } if ((0, utils_1.isFunction)(receiver[prop])) { return (...args) => { const result = receiver[prop](...args); return mapToProxy(result); }; } return receiver[prop]; } }); return proxy; } createGraphInspector(appOptions, container) { return (appOptions === null || appOptions === void 0 ? void 0 : appOptions.snapshot) ? new inspector_1.GraphInspector(container) : inspector_1.NoopGraphInspector; } } exports.BootstrapInitProject = BootstrapInitProject; exports.StartProjectInit = new BootstrapInitProject(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC9ib290c3RyYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsa0NBS2dCO0FBQ2hCLDZEQUF3RDtBQUN4RCwyQ0FBc0M7QUFDdEMsc0NBQTBDO0FBQzFDLHdDQUFpRDtBQUNqRCx5REFBb0Q7QUFDcEQsK0NBQTJDO0FBQzNDLHVDQUErQztBQVEvQyxvQ0FBNEM7QUFDNUMsMENBQW9DO0FBQ3BDLDRDQUtxQjtBQUNyQiwrREFBMEQ7QUFFMUQsTUFBYSxvQkFBb0I7SUFBakM7UUFDbUIsV0FBTSxHQUFHLElBQUksaUJBQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUN2RCxpQkFBWSxHQUFHLElBQUksQ0FBQTtRQUNuQixrQkFBYSxHQUFHLEtBQUssQ0FBQTtJQWlQL0IsQ0FBQztJQXBPUSxLQUFLLENBQUMsTUFBTSxDQUNqQixNQUFXLEVBQ1gsZUFBbUUsRUFDbkUsT0FBcUM7UUFFckMsTUFBTSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQztZQUNqRSxDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDO1lBQzVCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLGVBQWUsQ0FBQyxDQUFBO1FBRS9DLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxzQ0FBaUIsRUFBRSxDQUFBO1FBQ2pELE1BQU0sU0FBUyxHQUFHLElBQUksbUJBQVksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQ3JELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUE7UUFFdkUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDOUMsSUFBSSxD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SUFBZSxFQUFFLEVBQUU7d0JBQzVCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTt3QkFDL0QsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUE7b0JBQzNCLENBQUMsQ0FBQTtnQkFDSCxDQUFDO2dCQUNELElBQUksSUFBQSxrQkFBVSxFQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQy9CLE9BQU8sQ0FBQyxHQUFHLElBQWUsRUFBRSxFQUFFO3dCQUM1QixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTt3QkFDdEMsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUE7b0JBQzNCLENBQUMsQ0FBQTtnQkFDSCxDQUFDO2dCQUNELE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3ZCLENBQUM7U0FDRixDQUFDLENBQUE7UUFDRixPQUFPLEtBQXFCLENBQUE7SUFDOUIsQ0FBQztJQUVPLG9CQUFvQixDQUMxQixVQUE4QyxFQUM5QyxTQUF1QjtRQUV2QixPQUFPLENBQUEsVUFBVSxhQUFWLFVBQVUsdUJBQVYsVUFBVSxDQUFFLFFBQVE7WUFDekIsQ0FBQyxDQUFDLElBQUksMEJBQWMsQ0FBQyxTQUFTLENBQUM7WUFDL0IsQ0FBQyxDQUFDLDhCQUFrQixDQUFBO0lBQ3hCLENBQUM7Q0FDRjtBQXBQRCxvREFvUEM7QUFFWSxRQUFBLGdCQUFnQixHQUFHLElBQUksb0JBQW9CLEVBQUUsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFic3RyYWN0SHR0cEFkYXB0ZXIsXG4gIEluc3RhbmNlTG9hZGVyLFxuICBDb250YWluZXJJb0MsXG4gIEluamVjdG9yXG59IGZyb20gJy4uL2NvcmUnXG5pbXBvcnQgeyBBcHBsaWNhdGlvbkNvbmZpZyB9IGZyb20gJy4vYXBwbGljYXRpb24tY29uZmlnJ1xuaW1wb3J0IHsgTUVTU0FHRVMgfSBmcm9tICcuL2NvbnN0YW50cydcbmltcG9ydCB7IEV4Y2VwdGlvbnNab25lIH0gZnJvbSAnLi4vZXJyb3JzJ1xuaW1wb3J0IHsgbG9hZEFkYXB0ZXIsIHJldGhyb3cgfSBmcm9tICcuLi9oZWxwZXJzJ1xuaW1wb3J0IHsgTWV0YWRhdGFTY2FubmVyIH0gZnJvbSAnLi9tZXRhZGF0YS1zY2FubmVyJ1xuaW1wb3J0IHsgQXBwbGljYXRpb24gfSBmcm9tICcuL2FwcGxpY2F0aW9uJ1xuaW1wb3J0IHsgRGVwZW5kZW5jaWVzU2Nhbm5lciB9IGZyb20gJy4vc2Nhbm5lcidcbmltcG9ydCB7XG4gIEh0dHBTZXJ2ZXIsXG4gIEFwcGxpY2F0aW9uSW50ZXJmYWNlLFxuICBBcHBsaWNhdGlvbk9wdGlvbnNJbnRlcmZhY2UsXG4gIEFwcGxpY2F0aW9uQ29udGV4dE9wdGlvbnNJbnRlcmZhY2UsXG4gIEFwcGxpY2F0aW9uQ29udGV4dEludGVyZmFjZVxufSBmcm9tICcuLi9jb250cmFjdHMnXG5pbXBvcnQgeyBpc0Z1bmN0aW9uLCBpc05pbCB9IGZyb20gJy4uL3V0aWxzJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vc2VydmljZXMnXG5pbXBvcnQge1xuICBOb29wR3JhcGhJbnNwZWN0b3IsXG4gIEdyYXBoSW5zcGVjdG9yLFxuICBVdWlkRmFjdG9yeSxcbiAgVXVpZEZhY3RvcnlNb2RlXG59IGZyb20gJy4uL2luc3BlY3RvcidcbmltcG9ydCB7IEFwcGxpY2F0aW9uQ29udGV4dCB9IGZyb20gJy4vYXBwbGljYXRpb24tY29udGV4dCdcblxuZXhwb3J0IGNsYXNzIEJvb3RzdHJhcEluaXRQcm9qZWN0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBuZXcgTG9nZ2VyKG51bGwsIHsgdGltZXN0YW1wOiB0cnVlIH0pXG4gIHByaXZhdGUgYWJvcnRPbkVycm9yID0gdHJ1ZVxuICBwcml2YXRlIGF1dG9GbHVzaExvZ3MgPSBmYWxzZVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGU8VCBleHRlbmRzIEFwcGxpY2F0aW9uSW50ZXJmYWNlID0gQXBwbGljYXRpb25JbnRlcmZhY2U+KFxuICAgIG1vZHVsZTogYW55LFxuICAgIG9wdGlvbnM/OiBBcHBsaWNhdGlvbk9wdGlvbnNJbnRlcmZhY2VcbiAgKTogUHJvbWlzZTxUPlxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGU8VCBleHRlbmRzIEFwcGxpY2F0aW9uSW50ZXJmYWNlID0gQXBwbGljYXRpb25JbnRlcmZhY2U+KFxuICAgIG1vZHVsZTogYW55LFxuICAgIGh0dHBBZGFwdGVyOiBBYnN0cmFjdEh0dHBBZGFwdGVyLFxuICAgIG9wdGlvbnM/OiBBcHBsaWNhdGlvbk9wdGlvbnNJbnRlcmZhY2VcbiAgKTogUHJvbWlzZTxUPlxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGU8VCBleHRlbmRzIEFwcGxpY2F0aW9uSW50ZXJmYWNlID0gQXBwbGljYXRpb25JbnRlcmZhY2U+IChcbiAgICBtb2R1bGU6IGFueSxcbiAgICBzZXJ2ZXJPck9wdGlvbnM/OiBBYnN0cmFjdEh0dHBBZGFwdGVyIHwgQXBwbGljYXRpb25PcHRpb25zSW50ZXJmYWNlLFxuICAgIG9wdGlvbnM/OiBBcHBsaWNhdGlvbk9wdGlvbnNJbnRlcmZhY2VcbiAgKTogUHJvbWlzZTxUPiB7XG4gICAgY29uc3QgW2h0dHBTZXJ2ZXIsIGFwcE9wdGlvbnNdID0gdGhpcy5pc0h0dHBTZXJ2ZXIoc2VydmVyT3JPcHRpb25zKVxuICAgICAgPyBbc2VydmVyT3JPcHRpb25zLCBvcHRpb25zXVxuICAgICAgOiBbdGhpcy5jcmVhdGVIdHRwQWRhcHRlcigpLCBzZXJ2ZXJPck9wdGlvbnNdXG5cbiAgICBjb25zdCBhcHBsaWNhdGlvbkNvbmZpZyA9IG5ldyBBcHBsaWNhdGlvbkNvbmZpZygpXG4gICAgY29uc3QgY29udGFpbmVyID0gbmV3IENvbnRhaW5lcklvQyhhcHBsaWNhdGlvbkNvbmZpZylcbiAgICBjb25zdCBncmFwaEluc3BlY3RvciA9IHRoaXMuY3JlYXRlR3JhcGhJbnNwZWN0b3IoYXBwT3B0aW9ucywgY29udGFpbmVyKVxuXG4gICAgdGhpcy5zZXRBYm9ydE9uRXJyb3Ioc2VydmVyT3JPcHRpb25zLCBvcHRpb25zKVxuICAgIHRoaXMucmVnaXN0ZXJMb2dnZXJDb25maWd1cmF0aW9uKGFwcE9wdGlvbnMpXG5cbiAgICBhd2FpdCB0aGlzLmluaXRpYWxpemUoXG4gICAgICBtb2R1bGUsXG4gICAgICBjb250YWluZXIsXG4gICAgICBncmFwaEluc3BlY3RvcixcbiAgICAgIGFwcGxpY2F0aW9uQ29uZmlnLFxuICAgICAgYXBwT3B0aW9ucyxcbiAgICAgIGh0dHBTZXJ2ZXJcbiAgICApXG5cbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBBcHBsaWNhdGlvbihcbiAgICAgIGNvbnRhaW5lcixcbiAgICAgIGh0dHBTZXJ2ZXIsXG4gICAgICBhcHBsaWNhdGlvbkNvbmZpZyxcbiAgICAgIGdyYXBoSW5zcGVjdG9yLFxuICAgICAgYXBwT3B0aW9uc1xuICAgIClcbiAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmNyZWF0ZUNsZWFuSW5zdGFuY2UoaW5zdGFuY2UpXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlQWRhcHRlclByb3h5PFQ+KHRhcmdldCwgaHR0cFNlcnZlcilcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGVBcHBsaWNhdGlvbkNvbnRleHQgKFxuICAgIG1vZHVsZUNsczogYW55LFxuICAgIG9wdGlvbnM/OiBBcHBsaWNhdGlvbkNvbnRleHRPcHRpb25zSW50ZXJmYWNlXG4gICk6IFByb21pc2U8QXBwbGljYXRpb25Db250ZXh0SW50ZXJmYWNlPiB7XG4gICAgY29uc3QgYXBwbGljYXRpb25Db25maWcgPSBuZXcgQXBwbGljYXRpb25Db25maWcoKVxuICAgIGNvbnN0IGNvbnRhaW5lciA9IG5ldyBDb250YWluZXJJb0MoYXBwbGljYXRpb25Db25maWcpXG4gICAgY29uc3QgZ3JhcGhJbnNwZWN0b3IgPSB0aGlzLmNyZWF0ZUdyYXBoSW5zcGVjdG9yKG9wdGlvbnMsIGNvbnRhaW5lcilcblxuICAgIHRoaXMuc2V0QWJvcnRPbkVycm9yKG9wdGlvbnMpXG4gICAgdGhpcy5yZWdpc3RlckxvZ2dlckNvbmZpZ3VyYXRpb24ob3B0aW9ucylcblxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZShcbiAgICAgIG1vZHVsZUNscyxcbiAgICAgIGNvbnRhaW5lcixcbiAgICAgIGdyYXBoSW5zcGVjdG9yLFxuICAgICAgYXBwbGljYXRpb25Db25maWcsXG4gICAgICBvcHRpb25zXG4gICAgKVxuXG4gICAgY29uc3QgbW9kdWxlcyA9IGNvbnRhaW5lci5nZXRNb2R1bGVzKCkudmFsdWVzKClcbiAgICBjb25zdCByb290ID0gbW9kdWxlcy5uZXh0KCkudmFsdWVcblxuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNyZWF0ZUNsZWFuSW5zdGFuY2U8QXBwbGljYXRpb25Db250ZXh0PihcbiAgICAgIG5ldyBBcHBsaWNhdGlvbkNvbnRleHQoY29udGFpbmVyLCBvcHRpb25zLCByb290KVxuICAgIClcbiAgICBpZiAodGhpcy5hdXRvRmx1c2hMb2dzKSB7XG4gICAgICBjb250ZXh0LmZsdXNoTG9nc09uT3ZlcnJpZGUoKVxuICAgIH1cbiAgICByZXR1cm4gY29udGV4dC5pbml0KClcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ2xlYW5JbnN0YW5jZTxUPiAoaW5zdGFuY2U6IFQpOiBUIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVQcm94eShpbnN0YW5jZSlcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZSAoXG4gICAgbW9kdWxlOiBhbnksXG4gICAgY29udGFpbmVyOiBDb250YWluZXJJb0MsXG4gICAgZ3JhcGhJbnNwZWN0b3I6IEdyYXBoSW5zcGVjdG9yLFxuICAgIGNvbmZpZyA9IG5ldyBBcHBsaWNhdGlvbkNvbmZpZygpLFxuICAgIG9wdGlvbnM6IEFwcGxpY2F0aW9uQ29udGV4dE9wdGlvbnNJbnRlcmZhY2UgPSB7fSxcbiAgICBodHRwU2VydmVyOiBIdHRwU2VydmVyID0gbnVsbFxuICApIHtcbiAgICBVdWlkRmFjdG9yeS5tb2RlID0gb3B0aW9ucy5zbmFwc2hvdFxuICAgICAgPyBVdWlkRmFjdG9yeU1vZGUuRGV0ZXJtaW5pc3RpY1xuICAgICAgOiBVdWlkRmFjdG9yeU1vZGUuUmFuZG9tXG5cbiAgICBjb25zdCBpbmplY3RvciA9IG5ldyBJbmplY3Rvcih7IHByZXZpZXc6IG9wdGlvbnMucHJldmlldyB9KVxuICAgIGNvbnN0IGluc3RhbmNlTG9hZGVyID0gbmV3IEluc3RhbmNlTG9hZGVyKFxuICAgICAgY29udGFpbmVyLFxuICAgICAgaW5qZWN0b3IsXG4gICAgICBncmFwaEluc3BlY3RvclxuICAgIClcbiAgICBjb25zdCBtZXRhZGF0YVNjYW5uZXIgPSBuZXcgTWV0YWRhdGFTY2FubmVyKClcbiAgICBjb25zdCBkZXBlbmRlbmNpZXNTY2FubmVyID0gbmV3IERlcGVuZGVuY2llc1NjYW5uZXIoXG4gICAgICBjb250YWluZXIsXG4gICAgICBtZXRhZGF0YVNjYW5uZXIsXG4gICAgICBncmFwaEluc3BlY3RvcixcbiAgICAgIGNvbmZpZ1xuICAgIClcbiAgICBjb250YWluZXIuc2V0SHR0cEFkYXB0ZXIoaHR0cFNlcnZlcilcblxuICAgIGNvbnN0IHRlYXJkb3duID0gdGhpcy5hYm9ydE9uRXJyb3IgPT09IGZhbHNlID8gcmV0aHJvdyA6IHVuZGVmaW5lZFxuICAgIGF3YWl0IGh0dHBTZXJ2ZXI/LmluaXQoKVxuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvZ2dlci5sb2coTUVTU0FHRVMuQVBQTElDQVRJT05fU1RBUlQpXG5cbiAgICAgIGF3YWl0IEV4Y2VwdGlvbnNab25lLmFzeW5jUnVuKFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgZGVwZW5kZW5jaWVzU2Nhbm5lci5zY2FuKG1vZHVsZSlcbiAgICAgICAgICBhd2FpdCBpbnN0YW5jZUxvYWRlci5jcmVhdGVJbnN0YW5jZXNPZkRlcGVuZGVuY2llcygpXG4gICAgICAgICAgZGVwZW5kZW5jaWVzU2Nhbm5lci5hcHBseUFwcGxpY2F0aW9uUHJvdmlkZXJzKClcbiAgICAgICAgfSxcbiAgICAgICAgdGVhcmRvd24sXG4gICAgICAgIHRoaXMuYXV0b0ZsdXNoTG9nc1xuICAgICAgKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuaGFuZGxlSW5pdGlhbGl6YXRpb25FcnJvcihlKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlSW5pdGlhbGl6YXRpb25FcnJvciAoZXJyOiB1bmtub3duKSB7XG4gICAgaWYgKHRoaXMuYWJvcnRPbkVycm9yKSBwcm9jZXNzLmFib3J0KClcbiAgICByZXRocm93KGVycilcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlUHJveHkgKHRhcmdldDogYW55KSB7XG4gICAgY29uc3QgcHJveHkgPSB0aGlzLmNyZWF0ZUV4Y2VwdGlvblByb3h5KClcbiAgICByZXR1cm4gbmV3IFByb3h5KHRhcmdldCwge1xuICAgICAgZ2V0OiBwcm94eSxcbiAgICAgIHNldDogcHJveHlcbiAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVFeGNlcHRpb25Qcm94eSAoKSB7XG4gICAgcmV0dXJuIChyZWNlaXZlcjogUmVjb3JkPHN0cmluZywgYW55PiwgcHJvcDogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoIShwcm9wIGluIHJlY2VpdmVyKSkgcmV0dXJuXG4gICAgICBpZiAoaXNGdW5jdGlvbihyZWNlaXZlcltwcm9wXSkpXG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUV4Y2VwdGlvblpvbmUocmVjZWl2ZXIsIHByb3ApXG5cbiAgICAgIHJldHVybiByZWNlaXZlcltwcm9wXVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRXhjZXB0aW9uWm9uZSAoXG4gICAgcmVjZWl2ZXI6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcHJvcDogc3RyaW5nXG4gICk6IEZ1bmN0aW9uIHtcbiAgICBjb25zdCB0ZWFyZG93biA9IHRoaXMuYWJvcnRPbkVycm9yID09PSBmYWxzZSA/IHJldGhyb3cgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICBsZXQgcmVzdWx0OiB1bmtub3duXG4gICAgICBFeGNlcHRpb25zWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICByZXN1bHQgPSByZWNlaXZlcltwcm9wXSguLi5hcmdzKVxuICAgICAgfSwgdGVhcmRvd24pXG5cbiAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVnaXN0ZXJMb2dnZXJDb25maWd1cmF0aW9uIChcbiAgICBvcHRpb25zOiBBcHBsaWNhdGlvbkNvbnRleHRPcHRpb25zSW50ZXJmYWNlIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIGlmICghb3B0aW9ucykgcmV0dXJuXG4gICAgY29uc3QgeyBsb2dnZXIsIGJ1ZmZlckxvZ3MsIGF1dG9GbHVzaExvZ3MgfSA9IG9wdGlvbnNcbiAgICBpZiAoKGxvZ2dlciBhcyBib29sZWFuKSAhPT0gdHJ1ZSAmJiAhaXNOaWwobG9nZ2VyKSlcbiAgICAgIExvZ2dlci5vdmVycmlkZUxvZ2dlcihsb2dnZXIpXG5cbiAgICBpZiAoYnVmZmVyTG9ncykgTG9nZ2VyLmF0dGFjaEJ1ZmZlcigpXG5cbiAgICB0aGlzLmF1dG9GbHVzaExvZ3MgPSBhdXRvRmx1c2hMb2dzID8/IHRydWVcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlSHR0cEFkYXB0ZXI8VCA9IGFueT4gKGh0dHBTZXJ2ZXI/OiBUKTogQWJzdHJhY3RIdHRwQWRhcHRlciB7XG4gICAgY29uc3QgeyBFeHByZXNzQWRhcHRlciB9ID0gbG9hZEFkYXB0ZXIoJ2V4cHJlc3MnLCAnSFRUUCcsICgpID0+XG4gICAgICByZXF1aXJlKCcuLi9zZXJ2ZXInKVxuICAgIClcbiAgICByZXR1cm4gbmV3IEV4cHJlc3NBZGFwdGVyKGh0dHBTZXJ2ZXIpXG4gIH1cblxuICBwcm90ZWN0ZWQgaXNIdHRwU2VydmVyIChcbiAgICBzZXJ2ZXJPck9wdGlvbnM6IEFic3RyYWN0SHR0cEFkYXB0ZXIgfCBBcHBsaWNhdGlvbk9wdGlvbnNJbnRlcmZhY2VcbiAgKTogc2VydmVyT3JPcHRpb25zIGlzIEFic3RyYWN0SHR0cEFkYXB0ZXIge1xuICAgIHJldHVybiAhIShzZXJ2ZXJPck9wdGlvbnMgJiYgKHNlcnZlck9yT3B0aW9ucyBhcyBBYnN0cmFjdEh0dHBBZGFwdGVyKS5wYXRjaClcbiAgfVxuXG4gIHByaXZhdGUgc2V0QWJvcnRPbkVycm9yIChcbiAgICBzZXJ2ZXJPck9wdGlvbnM/OiBBYnN0cmFjdEh0dHBBZGFwdGVyIHwgQXBwbGljYXRpb25PcHRpb25zSW50ZXJmYWNlLFxuICAgIG9wdGlvbnM/OiBBcHBsaWNhdGlvbkNvbnRleHRPcHRpb25zSW50ZXJmYWNlIHwgQXBwbGljYXRpb25PcHRpb25zSW50ZXJmYWNlXG4gICkge1xuICAgIHRoaXMuYWJvcnRPbkVycm9yID0gdGhpcy5pc0h0dHBTZXJ2ZXIoc2VydmVyT3JPcHRpb25zKVxuICAgICAgPyAhKG9wdGlvbnMgJiYgb3B0aW9ucy5hYm9ydE9uRXJyb3IgPT09IGZhbHNlKVxuICAgICAgOiAhKHNlcnZlck9yT3B0aW9ucyAmJiBzZXJ2ZXJPck9wdGlvbnMuYWJvcnRPbkVycm9yID09PSBmYWxzZSlcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQWRhcHRlclByb3h5PFQ+IChhcHA6IEFwcGxpY2F0aW9uLCBhZGFwdGVyOiBIdHRwU2VydmVyKTogVCB7XG4gICAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkoYXBwLCB7XG4gICAgICBnZXQ6IChyZWNlaXZlcjogUmVjb3JkPHN0cmluZywgYW55PiwgcHJvcDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IG1hcFRvUHJveHkgPSAocmVzdWx0OiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2VcbiAgICAgICAgICAgID8gcmVzdWx0LnRoZW4obWFwVG9Qcm94eSlcbiAgICAgICAgICAgIDogcmVzdWx0IGluc3RhbmNlb2YgQXBwbGljYXRpb25cbiAgICAgICAgICAgID8gcHJveHlcbiAgICAgICAgICAgIDogcmVzdWx0XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIShwcm9wIGluIHJlY2VpdmVyKSAmJiBwcm9wIGluIGFkYXB0ZXIpIHtcbiAgICAgICAgICByZXR1cm4gKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jcmVhdGVFeGNlcHRpb25ab25lKGFkYXB0ZXIsIHByb3ApKC4uLmFyZ3MpXG4gICAgICAgICAgICByZXR1cm4gbWFwVG9Qcm94eShyZXN1bHQpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKHJlY2VpdmVyW3Byb3BdKSkge1xuICAgICAgICAgIHJldHVybiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSByZWNlaXZlcltwcm9wXSguLi5hcmdzKVxuICAgICAgICAgICAgcmV0dXJuIG1hcFRvUHJveHkocmVzdWx0KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVjZWl2ZXJbcHJvcF1cbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBwcm94eSBhcyB1bmtub3duIGFzIFRcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR3JhcGhJbnNwZWN0b3IgKFxuICAgIGFwcE9wdGlvbnM6IEFwcGxpY2F0aW9uQ29udGV4dE9wdGlvbnNJbnRlcmZhY2UsXG4gICAgY29udGFpbmVyOiBDb250YWluZXJJb0NcbiAgKSB7XG4gICAgcmV0dXJuIGFwcE9wdGlvbnM/LnNuYXBzaG90XG4gICAgICA/IG5ldyBHcmFwaEluc3BlY3Rvcihjb250YWluZXIpXG4gICAgICA6IE5vb3BHcmFwaEluc3BlY3RvclxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBTdGFydFByb2plY3RJbml0ID0gbmV3IEJvb3RzdHJhcEluaXRQcm9qZWN0KClcbiJdfQ==