UNPKG

@tsclean/core

Version:

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

207 lines 30.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Application = void 0; const os_1 = require("os"); const core_1 = require("../core"); const constants_1 = require("./constants"); const middleware_1 = require("../middleware"); const application_context_1 = require("./application-context"); const utils_1 = require("../utils"); const services_1 = require("../services"); const routes_resolver_1 = require("../router/routes-resolver"); const helpers_1 = require("../helpers"); const { SocketModule } = (0, helpers_1.optionalRequire)('../websockets/socket-module', () => require('../websockets/socket-module')); class Application extends application_context_1.ApplicationContext { constructor(container, httpAdapter, config, graphInspector, appOptions = {}) { super(container, appOptions); this.httpAdapter = httpAdapter; this.config = config; this.graphInspector = graphInspector; this.logger = new services_1.Logger(null, { timestamp: true }); this.middlewareModule = new middleware_1.MiddlewareModule(); this.middlewareContainer = new middleware_1.MiddlewareContainer(this.container); this.socketModule = SocketModule && new SocketModule(); this.isListening = false; this.selectContextModule(); this.registerHttpServer(); this.middlewareModule = new middleware_1.MiddlewareModule(); this.injector = new core_1.Injector({ preview: this.appOptions.preview }); this.routesResolver = new routes_resolver_1.RoutesResolver(this.container, this.config, this.injector, this.graphInspector); } async dispose() { this.socketModule && (await this.socketModule.close()); this.httpAdapter && (await this.httpAdapter.close()); } getHttpAdapter() { return this.httpAdapter; } registerHttpServer() { this.httpServer = this.createServer(); } getUnderlyingHttpServer() { return this.httpAdapter.getHttpServer(); } applyOptions() { if (!this.appOptions || !this.appOptions.cors) return undefined; const passCustomOptions = (0, utils_1.isObject)(this.appOptions.cors) || typeof this.appOptions.cors === 'function'; if (!passCustomOptions) return this.enableCors(); return this.enableCors(this.appOptions.cors); } createServer() { this.httpAdapter.initHttpServer(this.appOptions); return this.httpAdapter.getHttpServer(); } async registerModules() { this.registerWsModule(); await this.middlewareModule.register(this.middlewareContainer, this.container, this.config, this.injector, this.httpAdapter, this.graphInspector, this.appOptions); } registerWsModule() { if (!this.socketModule) { return; } this.socketModule.register(this.container, this.config, this.graphInspector, this.appOptions, this.httpServer); } async init() { var _a; this.applyOptions(); await ((_a = this.httpAdapter) === null || _a === void 0 ? void 0 : _a.init()); const useBodyParser = this.appOptions && this.appOptions.bodyParser !== false; useBodyParser && this.registerParserMiddleware(); await this.registerModules(); await this.registerRouter(); await this.registerRouterHooks(); this.isInitialized = true; this.logger.log(constants_1.MESSAGES.APPLICATION_READY); return this; } registerParserMiddleware() { this.httpAdapter.registerParserMiddleware(); } async registerRouter() { await this.registerMiddleware(this.httpAdapter); const prefix = this.config.getGlobalPrefix(); const basePath = (0, utils_1.addLeadingSlash)(prefix); this.routesResolver.resolve(this.httpAdapter, basePath); } async registerRouterHooks() { this.routesResolver.registerNotFoundHandler(); this.routesResolver.registerExceptionHandler(); } getHttpServer() { return this.httpServer; } use(...args) { this.httpAdapter.use(...args); return this; } enableCors(options) { this.httpAdapter.enableCors(options); } async listen(port, ...args) { !this.isInitialized && (await this.init()); return new Promise((resolve, reject) => { const errorHandler = (e) => { var _a; this.logger.error((_a = e === null || e === void 0 ? void 0 : e.toString) === null || _a === void 0 ? void 0 : _a.call(e)); reject(e); }; this.httpServer.once('error', errorHandler); const isCallbackInOriginalArgs = (0, utils_1.isFunction)(args[args.length - 1]); const listenFnArgs = isCallbackInOriginalArgs ? args.slice(0, args.length - 1) : args; this.httpAdapter.listen(port, ...listenFnArgs, (...originalCallbackArgs) => { if (originalCallbackArgs[0] instanceof Error) { return reject(originalCallbackArgs[0]); } const address = this.httpServer.address(); if (address) { this.httpServer.removeListener('error', errorHandler); this.isListening = true; resolve(this.httpServer); } if (isCallbackInOriginalArgs) { args[args.length - 1](...originalCallbackArgs); } }); }); } async getUrl() { return new Promise((resolve, reject) => { if (!this.isListening) { this.logger.error(constants_1.MESSAGES.CALL_LISTEN_FIRST); reject(constants_1.MESSAGES.CALL_LISTEN_FIRST); } const address = this.httpServer.address(); resolve(this.formatAddress(address)); }); } formatAddress(address) { if (typeof address === 'string') { if ((0, os_1.platform)() === 'win32') return address; const basePath = encodeURIComponent(address); return `${this.getProtocol()}+unix://${basePath}`; } let host = this.host(); if (address && address.family === 'IPv6') { if (host === '::') { host = '[::1]'; } else { host = `[${host}]`; } } else if (host === '0.0.0.0') { host = '127.0.0.1'; } return `${this.getProtocol()}://${host}:${address.port}`; } setGlobalPrefix(prefix, options) { this.config.setGlobalPrefix(prefix); if (options) { const exclude = (options === null || options === void 0 ? void 0 : options.exclude) ? (0, middleware_1.mapToExcludeRoute)(options.exclude.filter((item) => typeof item !== 'string')) : []; this.config.setGlobalPrefixOptions(Object.assign(Object.assign({}, options), { exclude })); } return this; } useWebSocketAdapter(adapter) { this.config.setIoAdapter(adapter); return this; } useGlobalFilters(...filters) { this.config.useGlobalFilters(...filters); return this; } useGlobalHandler(...handlers) { this.config.useGlobalHandlers(...handlers); return this; } useGlobalInterceptors(...interceptors) { this.config.useGlobalInterceptors(...interceptors); return this; } useGlobalAccessResources(...guards) { this.config.useGlobalAccessResource(...guards); return this; } host() { const address = this.httpServer.address(); if (typeof address === 'string') return undefined; return address && address.address; } getProtocol() { return this.appOptions && this.appOptions.httpsOptions ? 'https' : 'http'; } async registerMiddleware(instance) { await this.middlewareModule.registerMiddleware(this.middlewareContainer, instance); } } exports.Application = Application; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwL2FwcGxpY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJCQUE2QjtBQUU3QixrQ0FBcUU7QUFFckUsMkNBQXNDO0FBQ3RDLDhDQUF3RjtBQUN4RiwrREFBMEQ7QUFpQjFELG9DQUEwRTtBQUMxRSwwQ0FBb0M7QUFFcEMsK0RBQTBEO0FBQzFELHdDQUE0QztBQUc1QyxNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsSUFBQSx5QkFBZSxFQUN0Qyw2QkFBNkIsRUFDN0IsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLDZCQUE2QixDQUFDLENBQzdDLENBQUM7QUFFRixNQUFhLFdBQ1gsU0FBUSx3Q0FBK0M7SUFXdkQsWUFDRSxTQUF1QixFQUNOLFdBQXVCLEVBQ3ZCLE1BQXlCLEVBQ3pCLGNBQThCLEVBQy9DLGFBQTBDLEVBQUU7UUFFNUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUxYLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBQ3ZCLFdBQU0sR0FBTixNQUFNLENBQW1CO1FBQ3pCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQVo5QixXQUFNLEdBQUcsSUFBSSxpQkFBTSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1FBQ2hELHFCQUFnQixHQUFHLElBQUksNkJBQWdCLEVBQUUsQ0FBQTtRQUN6Qyx3QkFBbUIsR0FBRyxJQUFJLGdDQUFtQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUM3RCxpQkFBWSxHQUFHLFlBQVksSUFBSSxJQUFJLFlBQVksRUFBRSxDQUFDO1FBRzNELGdCQUFXLEdBQUcsS0FBSyxDQUFBO1FBV3pCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO1FBQzFCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1FBQ3pCLElBQUksQ0FBQyxn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Q0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO0lBQzNFLENBQUM7SUFFTyxLQUFLLENBQUMsa0JBQWtCLENBQUUsUUFBYTtRQUM3QyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FDNUMsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixRQUFRLENBQ1QsQ0FBQTtJQUNILENBQUM7Q0FDRjtBQW5SRCxrQ0FtUkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwbGF0Zm9ybSB9IGZyb20gJ29zJ1xuaW1wb3J0IHBhdGhUb1JlZ2V4cCBmcm9tICdwYXRoLXRvLXJlZ2V4cCdcbmltcG9ydCB7IEFic3RyYWN0SHR0cEFkYXB0ZXIsIENvbnRhaW5lcklvQywgSW5qZWN0b3IgfSBmcm9tICcuLi9jb3JlJ1xuaW1wb3J0IHsgQXBwbGljYXRpb25Db25maWcgfSBmcm9tICcuL2FwcGxpY2F0aW9uLWNvbmZpZydcbmltcG9ydCB7IE1FU1NBR0VTIH0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBtYXBUb0V4Y2x1ZGVSb3V0ZSwgTWlkZGxld2FyZUNvbnRhaW5lciwgTWlkZGxld2FyZU1vZHVsZSB9IGZyb20gJy4uL21pZGRsZXdhcmUnXG5pbXBvcnQgeyBBcHBsaWNhdGlvbkNvbnRleHQgfSBmcm9tICcuL2FwcGxpY2F0aW9uLWNvbnRleHQnXG5pbXBvcnQge1xuICBBY2Nlc3NSZXNvdXJjZUludGVyZmFjZSxcbiAgRXhjZXB0aW9uRmlsdGVySW50ZXJmYWNlLFxuICBIdHRwU2VydmVyLFxuICBBcHBsaWNhdGlvbkludGVyZmFjZSxcbiAgQXBwbGljYXRpb25PcHRpb25zSW50ZXJmYWNlLFxuICBJbnRlcmNlcHRvckludGVyZmFjZSxcbiAgR2xvYmFsUHJlZml4T3B0aW9uc0ludGVyZmFjZSxcbiAgUm91dGVJbmZvLFxuICBSZXNvbHZlckludGVyZmFjZSxcbiAgRXhjbHVkZVJvdXRlTWV0YWRhdGFJbnRlcmZhY2UsXG4gIENvcnNPcHRpb25zLFxuICBDb3JzT3B0aW9uc0RlbGVnYXRlLFxuICBIYW5kbGVyVHJhbnNmb3JtLFxuICBXZWJTb2NrZXRBZGFwdGVyXG59IGZyb20gJy4uL2NvbnRyYWN0cydcbmltcG9ydCB7IGFkZExlYWRpbmdTbGFzaCwgaXNGdW5jdGlvbiwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSAnLi4vdXRpbHMnXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi9zZXJ2aWNlcydcbmltcG9ydCB7IFJlcXVlc3RNZXRob2QgfSBmcm9tICcuLi9lbnVtcydcbmltcG9ydCB7IFJvdXRlc1Jlc29sdmVyIH0gZnJvbSAnLi4vcm91dGVyL3JvdXRlcy1yZXNvbHZlcidcbmltcG9ydCB7IG9wdGlvbmFsUmVxdWlyZSB9IGZyb20gJy4uL2hlbHBlcnMnXG5pbXBvcnQgeyBHcmFwaEluc3BlY3RvciB9IGZyb20gJy4uL2luc3BlY3RvcidcblxuY29uc3QgeyBTb2NrZXRNb2R1bGUgfSA9IG9wdGlvbmFsUmVxdWlyZShcbiAgJy4uL3dlYnNvY2tldHMvc29ja2V0LW1vZHVsZScsXG4gICgpID0+IHJlcXVpcmUoJy4uL3dlYnNvY2tldHMvc29ja2V0LW1vZHVsZScpLFxuKTtcblxuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uXG4gIGV4dGVuZHMgQXBwbGljYXRpb25Db250ZXh0PEFwcGxpY2F0aW9uT3B0aW9uc0ludGVyZmFjZT5cbiAgaW1wbGVtZW50cyBBcHBsaWNhdGlvbkludGVyZmFjZVxue1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbG9nZ2VyID0gbmV3IExvZ2dlcihudWxsLCB7IHRpbWVzdGFtcDogdHJ1ZSB9KVxuICBwcml2YXRlIHJlYWRvbmx5IG1pZGRsZXdhcmVNb2R1bGUgPSBuZXcgTWlkZGxld2FyZU1vZHVsZSgpXG4gIHByaXZhdGUgcmVhZG9ubHkgbWlkZGxld2FyZUNvbnRhaW5lciA9IG5ldyBNaWRkbGV3YXJlQ29udGFpbmVyKHRoaXMuY29udGFpbmVyKVxuICBwcml2YXRlIHJlYWRvbmx5IHNvY2tldE1vZHVsZSA9IFNvY2tldE1vZHVsZSAmJiBuZXcgU29ja2V0TW9kdWxlKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm91dGVzUmVzb2x2ZXI6IFJlc29sdmVySW50ZXJmYWNlXG4gIHByaXZhdGUgaHR0cFNlcnZlcjogYW55XG4gIHByaXZhdGUgaXNMaXN0ZW5pbmcgPSBmYWxzZVxuXG4gIGNvbnN0cnVjdG9yIChcbiAgICBjb250YWluZXI6IENvbnRhaW5lcklvQyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGh0dHBBZGFwdGVyOiBIdHRwU2VydmVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBBcHBsaWNhdGlvbkNvbmZpZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdyYXBoSW5zcGVjdG9yOiBHcmFwaEluc3BlY3RvcixcbiAgICBhcHBPcHRpb25zOiBBcHBsaWNhdGlvbk9wdGlvbnNJbnRlcmZhY2UgPSB7fVxuICApIHtcbiAgICBzdXBlcihjb250YWluZXIsIGFwcE9wdGlvbnMpXG5cbiAgICB0aGlzLnNlbGVjdENvbnRleHRNb2R1bGUoKVxuICAgIHRoaXMucmVnaXN0ZXJIdHRwU2VydmVyKClcbiAgICB0aGlzLm1pZGRsZXdhcmVNb2R1bGUgPSBuZXcgTWlkZGxld2FyZU1vZHVsZSgpO1xuICAgIHRoaXMuaW5qZWN0b3IgPSBuZXcgSW5qZWN0b3IoeyBwcmV2aWV3OiB0aGlzLmFwcE9wdGlvbnMucHJldmlldyB9KTtcbiAgICBcbiAgICB0aGlzLnJvdXRlc1Jlc29sdmVyID0gbmV3IFJvdXRlc1Jlc29sdmVyKFxuICAgICAgdGhpcy5jb250YWluZXIsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICB0aGlzLmdyYXBoSW5zcGVjdG9yLFxuICAgIClcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBkaXNwb3NlICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNvY2tldE1vZHVsZSAmJiAoYXdhaXQgdGhpcy5zb2NrZXRNb2R1bGUuY2xvc2UoKSk7XG4gICAgdGhpcy5odHRwQWRhcHRlciAmJiAoYXdhaXQgdGhpcy5odHRwQWRhcHRlci5jbG9zZSgpKVxuICB9XG5cbiAgcHVibGljIGdldEh0dHBBZGFwdGVyICgpOiBBYnN0cmFjdEh0dHBBZGFwdGVyIHtcbiAgICByZXR1cm4gdGhpcy5odHRwQWRhcHRlciBhcyBBYnN0cmFjdEh0dHBBZGFwdGVyXG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJIdHRwU2VydmVyICgpIHtcbiAgICB0aGlzLmh0dHBTZXJ2ZXIgPSB0aGlzLmNyZWF0ZVNlcnZlcigpXG4gIH1cblxuICBwdWJsaWMgZ2V0VW5kZXJseWluZ0h0dHBTZXJ2ZXI8VD4gKCk6IFQge1xuICAgIHJldHVybiB0aGlzLmh0dHBBZGFwdGVyLmdldEh0dHBTZXJ2ZXIoKVxuICB9XG5cbiAgcHVibGljIGFwcGx5T3B0aW9ucyAoKSB7XG4gICAgaWYgKCF0aGlzLmFwcE9wdGlvbnMgfHwgIXRoaXMuYXBwT3B0aW9ucy5jb3JzKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBjb25zdCBwYXNzQ3VzdG9tT3B0aW9ucyA9XG4gICAgICBpc09iamVjdCh0aGlzLmFwcE9wdGlvbnMuY29ycykgfHxcbiAgICAgIHR5cGVvZiB0aGlzLmFwcE9wdGlvbnMuY29ycyA9PT0gJ2Z1bmN0aW9uJ1xuICAgIGlmICghcGFzc0N1c3RvbU9wdGlvbnMpIHJldHVybiB0aGlzLmVuYWJsZUNvcnMoKVxuXG4gICAgcmV0dXJuIHRoaXMuZW5hYmxlQ29ycyhcbiAgICAgIHRoaXMuYXBwT3B0aW9ucy5jb3JzIGFzIENvcnNPcHRpb25zIHwgQ29yc09wdGlvbnNEZWxlZ2F0ZTxhbnk+XG4gICAgKVxuICB9XG5cbiAgcHVibGljIGNyZWF0ZVNlcnZlcjxUID0gYW55PiAoKTogVCB7XG4gICAgdGhpcy5odHRwQWRhcHRlci5pbml0SHR0cFNlcnZlcih0aGlzLmFwcE9wdGlvbnMpXG4gICAgcmV0dXJuIHRoaXMuaHR0cEFkYXB0ZXIuZ2V0SHR0cFNlcnZlcigpIGFzIFRcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZWdpc3Rlck1vZHVsZXMgKCkge1xuICAgIHRoaXMucmVnaXN0ZXJXc01vZHVsZSgpO1xuXG4gICAgYXdhaXQgdGhpcy5taWRkbGV3YXJlTW9kdWxlLnJlZ2lzdGVyKFxuICAgICAgdGhpcy5taWRkbGV3YXJlQ29udGFpbmVyLFxuICAgICAgdGhpcy5jb250YWluZXIsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICB0aGlzLmh0dHBBZGFwdGVyLFxuICAgICAgdGhpcy5ncmFwaEluc3BlY3RvcixcbiAgICAgIHRoaXMuYXBwT3B0aW9ucyxcbiAgICApXG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJXc01vZHVsZSgpIHtcbiAgICBpZiAoIXRoaXMuc29ja2V0TW9kdWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc29ja2V0TW9kdWxlLnJlZ2lzdGVyKFxuICAgICAgdGhpcy5jb250YWluZXIsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHRoaXMuZ3JhcGhJbnNwZWN0b3IsXG4gICAgICB0aGlzLmFwcE9wdGlvbnMsXG4gICAgICB0aGlzLmh0dHBTZXJ2ZXIsXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbml0ICgpOiBQcm9taXNlPHRoaXM+IHtcbiAgICB0aGlzLmFwcGx5T3B0aW9ucygpXG4gICAgYXdhaXQgdGhpcy5odHRwQWRhcHRlcj8uaW5pdCgpXG5cbiAgICBjb25zdCB1c2VCb2R5UGFyc2VyID1cbiAgICAgIHRoaXMuYXBwT3B0aW9ucyAmJiB0aGlzLmFwcE9wdGlvbnMuYm9keVBhcnNlciAhPT0gZmFsc2VcbiAgICB1c2VCb2R5UGFyc2VyICYmIHRoaXMucmVnaXN0ZXJQYXJzZXJNaWRkbGV3YXJlKClcblxuICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJNb2R1bGVzKClcbiAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyUm91dGVyKClcbiAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyUm91dGVySG9va3MoKVxuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZVxuICAgIHRoaXMubG9nZ2VyLmxvZyhNRVNTQUdFUy5BUFBMSUNBVElPTl9SRUFEWSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyUGFyc2VyTWlkZGxld2FyZSAoKSB7XG4gICAgdGhpcy5odHRwQWRhcHRlci5yZWdpc3RlclBhcnNlck1pZGRsZXdhcmUoKVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlZ2lzdGVyUm91dGVyICgpIHtcbiAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyTWlkZGxld2FyZSh0aGlzLmh0dHBBZGFwdGVyKVxuXG4gICAgY29uc3QgcHJlZml4ID0gdGhpcy5jb25maWcuZ2V0R2xvYmFsUHJlZml4KClcbiAgICBjb25zdCBiYXNlUGF0aCA9IGFkZExlYWRpbmdTbGFzaChwcmVmaXgpXG4gICAgdGhpcy5yb3V0ZXNSZXNvbHZlci5yZXNvbHZlKHRoaXMuaHR0cEFkYXB0ZXIsIGJhc2VQYXRoKVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlZ2lzdGVyUm91dGVySG9va3MgKCkge1xuICAgIHRoaXMucm91dGVzUmVzb2x2ZXIucmVnaXN0ZXJOb3RGb3VuZEhhbmRsZXIoKVxuICAgIHRoaXMucm91dGVzUmVzb2x2ZXIucmVnaXN0ZXJFeGNlcHRpb25IYW5kbGVyKClcbiAgfVxuXG4gIHB1YmxpYyBnZXRIdHRwU2VydmVyICgpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmVyXG4gIH1cblxuICBwdWJsaWMgdXNlICguLi5hcmdzOiBbYW55LCBhbnk/XSk6IHRoaXMge1xuICAgIHRoaXMuaHR0cEFkYXB0ZXIudXNlKC4uLmFyZ3MpXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHB1YmxpYyBlbmFibGVDb3JzIChvcHRpb25zPzogQ29yc09wdGlvbnMgfCBDb3JzT3B0aW9uc0RlbGVnYXRlPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLmh0dHBBZGFwdGVyLmVuYWJsZUNvcnMob3B0aW9ucylcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0ZW4ocG9ydDogbnVtYmVyIHwgc3RyaW5nKTogUHJvbWlzZTxhbnk+XG5cbiAgcHVibGljIGFzeW5jIGxpc3Rlbihwb3J0OiBudW1iZXIgfCBzdHJpbmcsIGhvc3RuYW1lOiBzdHJpbmcpOiBQcm9taXNlPGFueT5cblxuICBwdWJsaWMgYXN5bmMgbGlzdGVuIChwb3J0OiBudW1iZXIgfCBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxhbnk+IHtcbiAgICAhdGhpcy5pc0luaXRpYWxpemVkICYmIChhd2FpdCB0aGlzLmluaXQoKSlcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBlcnJvckhhbmRsZXIgPSAoZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGU/LnRvU3RyaW5nPy4oKSlcbiAgICAgICAgcmVqZWN0KGUpXG4gICAgICB9XG4gICAgICB0aGlzLmh0dHBTZXJ2ZXIub25jZSgnZXJyb3InLCBlcnJvckhhbmRsZXIpXG5cbiAgICAgIGNvbnN0IGlzQ2FsbGJhY2tJbk9yaWdpbmFsQXJncyA9IGlzRnVuY3Rpb24oYXJnc1thcmdzLmxlbmd0aCAtIDFdKVxuICAgICAgY29uc3QgbGlzdGVuRm5BcmdzID0gaXNDYWxsYmFja0luT3JpZ2luYWxBcmdzXG4gICAgICAgID8gYXJncy5zbGljZSgwLCBhcmdzLmxlbmd0aCAtIDEpXG4gICAgICAgIDogYXJnc1xuXG4gICAgICB0aGlzLmh0dHBBZGFwdGVyLmxpc3RlbihcbiAgICAgICAgcG9ydCxcbiAgICAgICAgLi4ubGlzdGVuRm5BcmdzLFxuICAgICAgICAoLi4ub3JpZ2luYWxDYWxsYmFja0FyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICAgIGlmIChvcmlnaW5hbENhbGxiYWNrQXJnc1swXSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KG9yaWdpbmFsQ2FsbGJhY2tBcmdzWzBdKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGFkZHJlc3MgPSB0aGlzLmh0dHBTZXJ2ZXIuYWRkcmVzcygpXG4gICAgICAgICAgaWYgKGFkZHJlc3MpIHtcbiAgICAgICAgICAgIHRoaXMuaHR0cFNlcnZlci5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBlcnJvckhhbmRsZXIpXG4gICAgICAgICAgICB0aGlzLmlzTGlzdGVuaW5nID0gdHJ1ZVxuICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLmh0dHBTZXJ2ZXIpXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpc0NhbGxiYWNrSW5PcmlnaW5hbEFyZ3MpIHtcbiAgICAgICAgICAgIGFyZ3NbYXJncy5sZW5ndGggLSAxXSguLi5vcmlnaW5hbENhbGxiYWNrQXJncylcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9KVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldFVybCAoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlzTGlzdGVuaW5nKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKE1FU1NBR0VTLkNBTExfTElTVEVOX0ZJUlNUKVxuICAgICAgICByZWplY3QoTUVTU0FHRVMuQ0FMTF9MSVNURU5fRklSU1QpXG4gICAgICB9XG4gICAgICBjb25zdCBhZGRyZXNzID0gdGhpcy5odHRwU2VydmVyLmFkZHJlc3MoKVxuICAgICAgcmVzb2x2ZSh0aGlzLmZvcm1hdEFkZHJlc3MoYWRkcmVzcykpXG4gICAgfSlcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0QWRkcmVzcyAoYWRkcmVzczogYW55KTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIGFkZHJlc3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAocGxhdGZvcm0oKSA9PT0gJ3dpbjMyJykgcmV0dXJuIGFkZHJlc3NcblxuICAgICAgY29uc3QgYmFzZVBhdGggPSBlbmNvZGVVUklDb21wb25lbnQoYWRkcmVzcylcbiAgICAgIHJldHVybiBgJHt0aGlzLmdldFByb3RvY29sKCl9K3VuaXg6Ly8ke2Jhc2VQYXRofWBcbiAgICB9XG4gICAgbGV0IGhvc3QgPSB0aGlzLmhvc3QoKVxuICAgIGlmIChhZGRyZXNzICYmIGFkZHJlc3MuZmFtaWx5ID09PSAnSVB2NicpIHtcbiAgICAgIGlmIChob3N0ID09PSAnOjonKSB7XG4gICAgICAgIGhvc3QgPSAnWzo6MV0nXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBob3N0ID0gYFske2hvc3R9XWBcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGhvc3QgPT09ICcwLjAuMC4wJykge1xuICAgICAgaG9zdCA9ICcxMjcuMC4wLjEnXG4gICAgfVxuXG4gICAgcmV0dXJuIGAke3RoaXMuZ2V0UHJvdG9jb2woKX06Ly8ke2hvc3R9OiR7YWRkcmVzcy5wb3J0fWBcbiAgfVxuXG4gIHB1YmxpYyBzZXRHbG9iYWxQcmVmaXggKFxuICAgIHByZWZpeDogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBHbG9iYWxQcmVmaXhPcHRpb25zSW50ZXJmYWNlXG4gICk6IHRoaXMge1xuICAgIHRoaXMuY29uZmlnLnNldEdsb2JhbFByZWZpeChwcmVmaXgpO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBjb25zdCBleGNsdWRlID0gb3B0aW9ucz8uZXhjbHVkZVxuICAgICAgICA/IG1hcFRvRXhjbHVkZVJvdXRlKG9wdGlvbnMuZXhjbHVkZS5maWx0ZXIoKGl0ZW0pOiBpdGVtIGlzIFJvdXRlSW5mbyA9PiB0eXBlb2YgaXRlbSAhPT0gJ3N0cmluZycpKVxuICAgICAgICA6IFtdO1xuICAgICAgdGhpcy5jb25maWcuc2V0R2xvYmFsUHJlZml4T3B0aW9ucyh7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIGV4Y2x1ZGUsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgdXNlV2ViU29ja2V0QWRhcHRlcihhZGFwdGVyOiBXZWJTb2NrZXRBZGFwdGVyKTogdGhpcyB7XG4gICAgdGhpcy5jb25maWcuc2V0SW9BZGFwdGVyKGFkYXB0ZXIpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIHVzZUdsb2JhbEZpbHRlcnMgKC4uLmZpbHRlcnM6IEV4Y2VwdGlvbkZpbHRlckludGVyZmFjZVtdKTogdGhpcyB7XG4gICAgdGhpcy5jb25maWcudXNlR2xvYmFsRmlsdGVycyguLi5maWx0ZXJzKVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBwdWJsaWMgdXNlR2xvYmFsSGFuZGxlciAoLi4uaGFuZGxlcnM6IEhhbmRsZXJUcmFuc2Zvcm08YW55PltdKTogdGhpcyB7XG4gICAgdGhpcy5jb25maWcudXNlR2xvYmFsSGFuZGxlcnMoLi4uaGFuZGxlcnMpXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHB1YmxpYyB1c2VHbG9iYWxJbnRlcmNlcHRvcnMgKC4uLmludGVyY2VwdG9yczogSW50ZXJjZXB0b3JJbnRlcmZhY2VbXSk6IHRoaXMge1xuICAgIHRoaXMuY29uZmlnLnVzZUdsb2JhbEludGVyY2VwdG9ycyguLi5pbnRlcmNlcHRvcnMpXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHB1YmxpYyB1c2VHbG9iYWxBY2Nlc3NSZXNvdXJjZXMgKC4uLmd1YXJkczogQWNjZXNzUmVzb3VyY2VJbnRlcmZhY2VbXSk6IHRoaXMge1xuICAgIHRoaXMuY29uZmlnLnVzZUdsb2JhbEFjY2Vzc1Jlc291cmNlKC4uLmd1YXJkcylcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHJpdmF0ZSBob3N0ICgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFkZHJlc3MgPSB0aGlzLmh0dHBTZXJ2ZXIuYWRkcmVzcygpXG4gICAgaWYgKHR5cGVvZiBhZGRyZXNzID09PSAnc3RyaW5nJykgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgcmV0dXJuIGFkZHJlc3MgJiYgYWRkcmVzcy5hZGRyZXNzXG4gIH1cblxuICBwcml2YXRlIGdldFByb3RvY29sICgpOiAnaHR0cCcgfCAnaHR0cHMnIHtcbiAgICByZXR1cm4gdGhpcy5hcHBPcHRpb25zICYmIHRoaXMuYXBwT3B0aW9ucy5odHRwc09wdGlvbnMgPyAnaHR0cHMnIDogJ2h0dHAnXG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyTWlkZGxld2FyZSAoaW5zdGFuY2U6IGFueSkge1xuICAgIGF3YWl0IHRoaXMubWlkZGxld2FyZU1vZHVsZS5yZWdpc3Rlck1pZGRsZXdhcmUoXG4gICAgICB0aGlzLm1pZGRsZXdhcmVDb250YWluZXIsXG4gICAgICBpbnN0YW5jZVxuICAgIClcbiAgfVxufVxuIl19