UNPKG

@tsclean/core

Version:

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

255 lines 32.6 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var ConsoleLogger_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConsoleLogger = void 0; const decorators_1 = require("../decorators"); const cli_colors_1 = require("../utils/cli-colors"); const shared_utils_1 = require("../utils/shared.utils"); const is_log_level_enabled_util_1 = require("./utils/is-log-level-enabled.util"); const DEFAULT_LOG_LEVELS = [ 'log', 'error', 'warn', 'debug', 'verbose', 'fatal' ]; const dateTimeFormatter = new Intl.DateTimeFormat(undefined, { year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', day: '2-digit', month: '2-digit' }); let ConsoleLogger = ConsoleLogger_1 = class ConsoleLogger { constructor(context, options = {}) { this.context = context; this.options = options; if (!options.logLevels) { options.logLevels = DEFAULT_LOG_LEVELS; } if (context) { this.originalContext = context; } } log(message, ...optionalParams) { if (!this.isLevelEnabled('log')) { return; } const { messages, context } = this.getContextAndMessagesToPrint([ message, ...optionalParams ]); this.printMessages(messages, context, 'log'); } error(message, ...optionalParams) { if (!this.isLevelEnabled('error')) { return; } const { messages, context, stack } = this.getContextAndStackAndMessagesToPrint([message, ...optionalParams]); this.printMessages(messages, context, 'error', 'stderr'); this.printStackTrace(stack); } warn(message, ...optionalParams) { if (!this.isLevelEnabled('warn')) { return; } const { messages, context } = this.getContextAndMessagesToPrint([ message, ...optionalParams ]); this.printMessages(messages, context, 'warn'); } debug(message, ...optionalParams) { if (!this.isLevelEnabled('debug')) { return; } const { messages, context } = this.getContextAndMessagesToPrint([ message, ...optionalParams ]); this.printMessages(messages, context, 'debug'); } verbose(message, ...optionalParams) { if (!this.isLevelEnabled('verbose')) { return; } const { messages, context } = this.getContextAndMessagesToPrint([ message, ...optionalParams ]); this.printMessages(messages, context, 'verbose'); } fatal(message, ...optionalParams) { if (!this.isLevelEnabled('fatal')) { return; } const { messages, context } = this.getContextAndMessagesToPrint([ message, ...optionalParams ]); this.printMessages(messages, context, 'fatal'); } setLogLevels(levels) { if (!this.options) { this.options = {}; } this.options.logLevels = levels; } setContext(context) { this.context = context; } resetContext() { this.context = this.originalContext; } isLevelEnabled(level) { var _a; const logLevels = (_a = this.options) === null || _a === void 0 ? void 0 : _a.logLevels; return (0, is_log_level_enabled_util_1.isLogLevelEnabled)(level, logLevels); } getTimestamp() { return dateTimeFormatter.format(Date.now()); } printMessages(messages, context = '', logLevel = 'log', writeStreamType) { messages.forEach(message => { const pidMessage = this.formatPid(process.pid); const contextMessage = this.formatContext(context); const timestampDiff = this.updateAndGetTimestampDiff(); const formattedLogLevel = logLevel.toUpperCase().padStart(7, ' '); const formattedMessage = this.formatMessage(logLevel, message, pidMessage, formattedLogLevel, contextMessage, timestampDiff); process[writeStreamType !== null && writeStreamType !== void 0 ? writeStreamType : 'stdout'].write(formattedMessage); }); } formatPid(pid) { return `[TSClean] ${pid} - `; } formatContext(context) { return context ? (0, cli_colors_1.yellow)(`[${context}] `) : ''; } formatMessage(logLevel, message, pidMessage, formattedLogLevel, contextMessage, timestampDiff) { const output = this.stringifyMessage(message, logLevel); pidMessage = this.colorize(pidMessage, logLevel); formattedLogLevel = this.colorize(formattedLogLevel, logLevel); return `${pidMessage}${this.getTimestamp()} ${formattedLogLevel} ${contextMessage}${output}${timestampDiff}\n`; } stringifyMessage(message, logLevel) { if ((0, shared_utils_1.isFunction)(message)) { const messageAsStr = Function.prototype.toString.call(message); const isClass = messageAsStr.startsWith('class '); if (isClass) { return this.stringifyMessage(message.name, logLevel); } return this.stringifyMessage(message, logLevel); } return (0, shared_utils_1.isPlainObject)(message) || Array.isArray(message) ? `${this.colorize('Object:', logLevel)}\n${JSON.stringify(message, (key, value) => typeof value === 'bigint' ? value.toString() : value, 2)}\n` : this.colorize(message, logLevel); } colorize(message, logLevel) { const color = this.getColorByLogLevel(logLevel); return color(message); } printStackTrace(stack) { if (!stack) { return; } process.stderr.write(`${stack}\n`); } updateAndGetTimestampDiff() { var _a; const includeTimestamp = ConsoleLogger_1.lastTimestampAt && ((_a = this.options) === null || _a === void 0 ? void 0 : _a.timestamp); const result = includeTimestamp ? this.formatTimestampDiff(Date.now() - ConsoleLogger_1.lastTimestampAt) : ''; ConsoleLogger_1.lastTimestampAt = Date.now(); return result; } formatTimestampDiff(timestampDiff) { return (0, cli_colors_1.yellow)(` +${timestampDiff}ms`); } getContextAndMessagesToPrint(args) { if ((args === null || args === void 0 ? void 0 : args.length) <= 1) { return { messages: args, context: this.context }; } const lastElement = args[args.length - 1]; const isContext = (0, shared_utils_1.isString)(lastElement); if (!isContext) { return { messages: args, context: this.context }; } return { context: lastElement, messages: args.slice(0, args.length - 1) }; } getContextAndStackAndMessagesToPrint(args) { if (args.length === 2) { return this.isStackFormat(args[1]) ? { messages: [args[0]], stack: args[1], context: this.context } : { messages: [args[0]], context: args[1] }; } const { messages, context } = this.getContextAndMessagesToPrint(args); if ((messages === null || messages === void 0 ? void 0 : messages.length) <= 1) { return { messages, context }; } const lastElement = messages[messages.length - 1]; const isStack = (0, shared_utils_1.isString)(lastElement); if (!isStack && !(0, shared_utils_1.isUndefined)(lastElement)) { return { messages, context }; } return { stack: lastElement, messages: messages.slice(0, messages.length - 1), context }; } isStackFormat(stack) { if (!(0, shared_utils_1.isString)(stack) && !(0, shared_utils_1.isUndefined)(stack)) { return false; } return /^(.)+\n\s+at .+:\d+:\d+/.test(stack); } getColorByLogLevel(level) { switch (level) { case 'debug': return cli_colors_1.clc.magentaBright; case 'warn': return cli_colors_1.clc.yellow; case 'error': return cli_colors_1.clc.red; case 'verbose': return cli_colors_1.clc.cyanBright; case 'fatal': return cli_colors_1.clc.bold; default: return cli_colors_1.clc.green; } } }; exports.ConsoleLogger = ConsoleLogger; exports.ConsoleLogger = ConsoleLogger = ConsoleLogger_1 = __decorate([ (0, decorators_1.Service)(), __param(0, (0, decorators_1.Optional)()), __param(1, (0, decorators_1.Optional)()), __metadata("design:paramtypes", [String, Object]) ], ConsoleLogger); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc29sZS1sb2dnZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9jb25zb2xlLWxvZ2dlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw4Q0FBaUQ7QUFFakQsb0RBQWlEO0FBQ2pELHdEQUs4QjtBQUM5QixpRkFBcUU7QUFPckUsTUFBTSxrQkFBa0IsR0FBZTtJQUNyQyxLQUFLO0lBQ0wsT0FBTztJQUNQLE1BQU07SUFDTixPQUFPO0lBQ1AsU0FBUztJQUNULE9BQU87Q0FDUixDQUFBO0FBRUQsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFO0lBQzNELElBQUksRUFBRSxTQUFTO0lBQ2YsSUFBSSxFQUFFLFNBQVM7SUFDZixNQUFNLEVBQUUsU0FBUztJQUNqQixNQUFNLEVBQUUsU0FBUztJQUNqQixHQUFHLEVBQUUsU0FBUztJQUNkLEtBQUssRUFBRSxTQUFTO0NBQ2pCLENBQUMsQ0FBQTtBQUdLLElBQU0sYUFBYSxxQkFBbkIsTUFBTSxhQUFhO0lBT3hCLFlBRVksT0FBZ0IsRUFFaEIsVUFBZ0MsRUFBRTtRQUZsQyxZQUFPLEdBQVAsT0FBTyxDQUFTO1FBRWhCLFlBQU8sR0FBUCxPQUFPLENBQTJCO1FBRTVDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdkIsT0FBTyxDQUFDLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQTtRQUN4QyxDQUFDO1FBQ0QsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFBO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBSUQsR0FBRyxDQUFFLE9BQVksRUFBRSxHQUFHLGNBQXFCO1FBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEMsT0FBTTtRQUNS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QUM7SUFFTyxhQUFhLENBQUUsS0FBYztRQUNuQyxJQUFJLENBQUMsSUFBQSx1QkFBUSxFQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBQSwwQkFBVyxFQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUMsT0FBTyxLQUFLLENBQUE7UUFDZCxDQUFDO1FBRUQsT0FBTyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDOUMsQ0FBQztJQUVPLGtCQUFrQixDQUFFLEtBQWU7UUFDekMsUUFBUSxLQUFLLEVBQUUsQ0FBQztZQUNkLEtBQUssT0FBTztnQkFDVixPQUFPLGdCQUFHLENBQUMsYUFBYSxDQUFBO1lBQzFCLEtBQUssTUFBTTtnQkFDVCxPQUFPLGdCQUFHLENBQUMsTUFBTSxDQUFBO1lBQ25CLEtBQUssT0FBTztnQkFDVixPQUFPLGdCQUFHLENBQUMsR0FBRyxDQUFBO1lBQ2hCLEtBQUssU0FBUztnQkFDWixPQUFPLGdCQUFHLENBQUMsVUFBVSxDQUFBO1lBQ3ZCLEtBQUssT0FBTztnQkFDVixPQUFPLGdCQUFHLENBQUMsSUFBSSxDQUFBO1lBQ2pCO2dCQUNFLE9BQU8sZ0JBQUcsQ0FBQyxLQUFLLENBQUE7UUFDcEIsQ0FBQztJQUNILENBQUM7Q0FDRixDQUFBO0FBOVJZLHNDQUFhO3dCQUFiLGFBQWE7SUFEekIsSUFBQSxvQkFBTyxHQUFFO0lBU0wsV0FBQSxJQUFBLHFCQUFRLEdBQUUsQ0FBQTtJQUVWLFdBQUEsSUFBQSxxQkFBUSxHQUFFLENBQUE7O0dBVkYsYUFBYSxDQThSekIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcHRpb25hbCwgU2VydmljZSB9IGZyb20gJy4uL2RlY29yYXRvcnMnXG5pbXBvcnQgeyBMb2dnZXJTZXJ2aWNlLCBMb2dMZXZlbCB9IGZyb20gJy4vbG9nZ2VyLnNlcnZpY2UnXG5pbXBvcnQgeyBjbGMsIHllbGxvdyB9IGZyb20gJy4uL3V0aWxzL2NsaS1jb2xvcnMnXG5pbXBvcnQge1xuICBpc0Z1bmN0aW9uLFxuICBpc1BsYWluT2JqZWN0LFxuICBpc1N0cmluZyxcbiAgaXNVbmRlZmluZWRcbn0gZnJvbSAnLi4vdXRpbHMvc2hhcmVkLnV0aWxzJ1xuaW1wb3J0IHsgaXNMb2dMZXZlbEVuYWJsZWQgfSBmcm9tICcuL3V0aWxzL2lzLWxvZy1sZXZlbC1lbmFibGVkLnV0aWwnXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uc29sZUxvZ2dlck9wdGlvbnMge1xuICBsb2dMZXZlbHM/OiBMb2dMZXZlbFtdXG4gIHRpbWVzdGFtcD86IGJvb2xlYW5cbn1cblxuY29uc3QgREVGQVVMVF9MT0dfTEVWRUxTOiBMb2dMZXZlbFtdID0gW1xuICAnbG9nJyxcbiAgJ2Vycm9yJyxcbiAgJ3dhcm4nLFxuICAnZGVidWcnLFxuICAndmVyYm9zZScsXG4gICdmYXRhbCdcbl1cblxuY29uc3QgZGF0ZVRpbWVGb3JtYXR0ZXIgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdCh1bmRlZmluZWQsIHtcbiAgeWVhcjogJ251bWVyaWMnLFxuICBob3VyOiAnbnVtZXJpYycsXG4gIG1pbnV0ZTogJ251bWVyaWMnLFxuICBzZWNvbmQ6ICdudW1lcmljJyxcbiAgZGF5OiAnMi1kaWdpdCcsXG4gIG1vbnRoOiAnMi1kaWdpdCdcbn0pXG5cbkBTZXJ2aWNlKClcbmV4cG9ydCBjbGFzcyBDb25zb2xlTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyU2VydmljZSB7XG4gIHByaXZhdGUgc3RhdGljIGxhc3RUaW1lc3RhbXBBdD86IG51bWJlclxuICBwcml2YXRlIG9yaWdpbmFsQ29udGV4dD86IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKClcbiAgY29uc3RydWN0b3IoY29udGV4dDogc3RyaW5nKVxuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBzdHJpbmcsIG9wdGlvbnM6IENvbnNvbGVMb2dnZXJPcHRpb25zKVxuICBjb25zdHJ1Y3RvciAoXG4gICAgQE9wdGlvbmFsKClcbiAgICBwcm90ZWN0ZWQgY29udGV4dD86IHN0cmluZyxcbiAgICBAT3B0aW9uYWwoKVxuICAgIHByb3RlY3RlZCBvcHRpb25zOiBDb25zb2xlTG9nZ2VyT3B0aW9ucyA9IHt9XG4gICkge1xuICAgIGlmICghb3B0aW9ucy5sb2dMZXZlbHMpIHtcbiAgICAgIG9wdGlvbnMubG9nTGV2ZWxzID0gREVGQVVMVF9MT0dfTEVWRUxTXG4gICAgfVxuICAgIGlmIChjb250ZXh0KSB7XG4gICAgICB0aGlzLm9yaWdpbmFsQ29udGV4dCA9IGNvbnRleHRcbiAgICB9XG4gIH1cblxuICBsb2cobWVzc2FnZTogYW55LCBjb250ZXh0Pzogc3RyaW5nKTogdm9pZFxuICBsb2cobWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogWy4uLmFueSwgc3RyaW5nP10pOiB2b2lkXG4gIGxvZyAobWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pIHtcbiAgICBpZiAoIXRoaXMuaXNMZXZlbEVuYWJsZWQoJ2xvZycpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgeyBtZXNzYWdlcywgY29udGV4dCB9ID0gdGhpcy5nZXRDb250ZXh0QW5kTWVzc2FnZXNUb1ByaW50KFtcbiAgICAgIG1lc3NhZ2UsXG4gICAgICAuLi5vcHRpb25hbFBhcmFtc1xuICAgIF0pXG4gICAgdGhpcy5wcmludE1lc3NhZ2VzKG1lc3NhZ2VzLCBjb250ZXh0LCAnbG9nJylcbiAgfVxuXG4gIGVycm9yKG1lc3NhZ2U6IGFueSwgc3RhY2tPckNvbnRleHQ/OiBzdHJpbmcpOiB2b2lkXG4gIGVycm9yKG1lc3NhZ2U6IGFueSwgc3RhY2s/OiBzdHJpbmcsIGNvbnRleHQ/OiBzdHJpbmcpOiB2b2lkXG4gIGVycm9yKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IFsuLi5hbnksIHN0cmluZz8sIHN0cmluZz9dKTogdm9pZFxuICBlcnJvciAobWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pIHtcbiAgICBpZiAoIXRoaXMuaXNMZXZlbEVuYWJsZWQoJ2Vycm9yJykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB7IG1lc3NhZ2VzLCBjb250ZXh0LCBzdGFjayB9ID1cbiAgICAgIHRoaXMuZ2V0Q29udGV4dEFuZFN0YWNrQW5kTWVzc2FnZXNUb1ByaW50KFttZXNzYWdlLCAuLi5vcHRpb25hbFBhcmFtc10pXG5cbiAgICB0aGlzLnByaW50TWVzc2FnZXMobWVzc2FnZXMsIGNvbnRleHQsICdlcnJvcicsICdzdGRlcnInKVxuICAgIHRoaXMucHJpbnRTdGFja1RyYWNlKHN0YWNrKVxuICB9XG5cbiAgd2FybihtZXNzYWdlOiBhbnksIGNvbnRleHQ/OiBzdHJpbmcpOiB2b2lkXG4gIHdhcm4obWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogWy4uLmFueSwgc3RyaW5nP10pOiB2b2lkXG4gIHdhcm4gKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XG4gICAgaWYgKCF0aGlzLmlzTGV2ZWxFbmFibGVkKCd3YXJuJykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB7IG1lc3NhZ2VzLCBjb250ZXh0IH0gPSB0aGlzLmdldENvbnRleHRBbmRNZXNzYWdlc1RvUHJpbnQoW1xuICAgICAgbWVzc2FnZSxcbiAgICAgIC4uLm9wdGlvbmFsUGFyYW1zXG4gICAgXSlcbiAgICB0aGlzLnByaW50TWVzc2FnZXMobWVzc2FnZXMsIGNvbnRleHQsICd3YXJuJylcbiAgfVxuXG4gIGRlYnVnKG1lc3NhZ2U6IGFueSwgY29udGV4dD86IHN0cmluZyk6IHZvaWRcbiAgZGVidWcobWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogWy4uLmFueSwgc3RyaW5nP10pOiB2b2lkXG4gIGRlYnVnIChtZXNzYWdlOiBhbnksIC4uLm9wdGlvbmFsUGFyYW1zOiBhbnlbXSkge1xuICAgIGlmICghdGhpcy5pc0xldmVsRW5hYmxlZCgnZGVidWcnKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNvbnN0IHsgbWVzc2FnZXMsIGNvbnRleHQgfSA9IHRoaXMuZ2V0Q29udGV4dEFuZE1lc3NhZ2VzVG9QcmludChbXG4gICAgICBtZXNzYWdlLFxuICAgICAgLi4ub3B0aW9uYWxQYXJhbXNcbiAgICBdKVxuICAgIHRoaXMucHJpbnRNZXNzYWdlcyhtZXNzYWdlcywgY29udGV4dCwgJ2RlYnVnJylcbiAgfVxuXG4gIHZlcmJvc2UobWVzc2FnZTogYW55LCBjb250ZXh0Pzogc3RyaW5nKTogdm9pZFxuICB2ZXJib3NlKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IFsuLi5hbnksIHN0cmluZz9dKTogdm9pZFxuICB2ZXJib3NlIChtZXNzYWdlOiBhbnksIC4uLm9wdGlvbmFsUGFyYW1zOiBhbnlbXSkge1xuICAgIGlmICghdGhpcy5pc0xldmVsRW5hYmxlZCgndmVyYm9zZScpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgeyBtZXNzYWdlcywgY29udGV4dCB9ID0gdGhpcy5nZXRDb250ZXh0QW5kTWVzc2FnZXNUb1ByaW50KFtcbiAgICAgIG1lc3NhZ2UsXG4gICAgICAuLi5vcHRpb25hbFBhcmFtc1xuICAgIF0pXG4gICAgdGhpcy5wcmludE1lc3NhZ2VzKG1lc3NhZ2VzLCBjb250ZXh0LCAndmVyYm9zZScpXG4gIH1cblxuICBmYXRhbChtZXNzYWdlOiBhbnksIGNvbnRleHQ/OiBzdHJpbmcpOiB2b2lkXG4gIGZhdGFsKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IFsuLi5hbnksIHN0cmluZz9dKTogdm9pZFxuICBmYXRhbCAobWVzc2FnZTogYW55LCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pIHtcbiAgICBpZiAoIXRoaXMuaXNMZXZlbEVuYWJsZWQoJ2ZhdGFsJykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB7IG1lc3NhZ2VzLCBjb250ZXh0IH0gPSB0aGlzLmdldENvbnRleHRBbmRNZXNzYWdlc1RvUHJpbnQoW1xuICAgICAgbWVzc2FnZSxcbiAgICAgIC4uLm9wdGlvbmFsUGFyYW1zXG4gICAgXSlcbiAgICB0aGlzLnByaW50TWVzc2FnZXMobWVzc2FnZXMsIGNvbnRleHQsICdmYXRhbCcpXG4gIH1cblxuICBzZXRMb2dMZXZlbHMgKGxldmVsczogTG9nTGV2ZWxbXSkge1xuICAgIGlmICghdGhpcy5vcHRpb25zKSB7XG4gICAgICB0aGlzLm9wdGlvbnMgPSB7fVxuICAgIH1cbiAgICB0aGlzLm9wdGlvbnMubG9nTGV2ZWxzID0gbGV2ZWxzXG4gIH1cblxuICBzZXRDb250ZXh0IChjb250ZXh0OiBzdHJpbmcpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0XG4gIH1cblxuICByZXNldENvbnRleHQgKCkge1xuICAgIHRoaXMuY29udGV4dCA9IHRoaXMub3JpZ2luYWxDb250ZXh0XG4gIH1cblxuICBpc0xldmVsRW5hYmxlZCAobGV2ZWw6IExvZ0xldmVsKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbG9nTGV2ZWxzID0gdGhpcy5vcHRpb25zPy5sb2dMZXZlbHNcbiAgICByZXR1cm4gaXNMb2dMZXZlbEVuYWJsZWQobGV2ZWwsIGxvZ0xldmVscylcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRUaW1lc3RhbXAgKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGRhdGVUaW1lRm9ybWF0dGVyLmZvcm1hdChEYXRlLm5vdygpKVxuICB9XG5cbiAgcHJvdGVjdGVkIHByaW50TWVzc2FnZXMgKFxuICAgIG1lc3NhZ2VzOiB1bmtub3duW10sXG4gICAgY29udGV4dCA9ICcnLFxuICAgIGxvZ0xldmVsOiBMb2dMZXZlbCA9ICdsb2cnLFxuICAgIHdyaXRlU3RyZWFtVHlwZT86ICdzdGRvdXQnIHwgJ3N0ZGVycidcbiAgKSB7XG4gICAgbWVzc2FnZXMuZm9yRWFjaChtZXNzYWdlID0+IHtcbiAgICAgIGNvbnN0IHBpZE1lc3NhZ2UgPSB0aGlzLmZvcm1hdFBpZChwcm9jZXNzLnBpZClcbiAgICAgIGNvbnN0IGNvbnRleHRNZXNzYWdlID0gdGhpcy5mb3JtYXRDb250ZXh0KGNvbnRleHQpXG4gICAgICBjb25zdCB0aW1lc3RhbXBEaWZmID0gdGhpcy51cGRhdGVBbmRHZXRUaW1lc3RhbXBEaWZmKClcbiAgICAgIGNvbnN0IGZvcm1hdHRlZExvZ0xldmVsID0gbG9nTGV2ZWwudG9VcHBlckNhc2UoKS5wYWRTdGFydCg3LCAnICcpXG4gICAgICBjb25zdCBmb3JtYXR0ZWRNZXNzYWdlID0gdGhpcy5mb3JtYXRNZXNzYWdlKFxuICAgICAgICBsb2dMZXZlbCxcbiAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgcGlkTWVzc2FnZSxcbiAgICAgICAgZm9ybWF0dGVkTG9nTGV2ZWwsXG4gICAgICAgIGNvbnRleHRNZXNzYWdlLFxuICAgICAgICB0aW1lc3RhbXBEaWZmXG4gICAgICApXG5cbiAgICAgIHByb2Nlc3Nbd3JpdGVTdHJlYW1UeXBlID8/ICdzdGRvdXQnXS53cml0ZShmb3JtYXR0ZWRNZXNzYWdlKVxuICAgIH0pXG4gIH1cblxuICBwcm90ZWN0ZWQgZm9ybWF0UGlkIChwaWQ6IG51bWJlcikge1xuICAgIHJldHVybiBgW1RTQ2xlYW5dICR7cGlkfSAgLSBgXG4gIH1cblxuICBwcm90ZWN0ZWQgZm9ybWF0Q29udGV4dCAoY29udGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY29udGV4dCA/IHllbGxvdyhgWyR7Y29udGV4dH1dIGApIDogJydcbiAgfVxuXG4gIHByb3RlY3RlZCBmb3JtYXRNZXNzYWdlIChcbiAgICBsb2dMZXZlbDogTG9nTGV2ZWwsXG4gICAgbWVzc2FnZTogdW5rbm93bixcbiAgICBwaWRNZXNzYWdlOiBzdHJpbmcsXG4gICAgZm9ybWF0dGVkTG9nTGV2ZWw6IHN0cmluZyxcbiAgICBjb250ZXh0TWVzc2FnZTogc3RyaW5nLFxuICAgIHRpbWVzdGFtcERpZmY6IHN0cmluZ1xuICApIHtcbiAgICBjb25zdCBvdXRwdXQgPSB0aGlzLnN0cmluZ2lmeU1lc3NhZ2UobWVzc2FnZSwgbG9nTGV2ZWwpXG4gICAgcGlkTWVzc2FnZSA9IHRoaXMuY29sb3JpemUocGlkTWVzc2FnZSwgbG9nTGV2ZWwpXG4gICAgZm9ybWF0dGVkTG9nTGV2ZWwgPSB0aGlzLmNvbG9yaXplKGZvcm1hdHRlZExvZ0xldmVsLCBsb2dMZXZlbClcbiAgICByZXR1cm4gYCR7cGlkTWVzc2FnZX0ke3RoaXMuZ2V0VGltZXN0YW1wKCl9ICR7Zm9ybWF0dGVkTG9nTGV2ZWx9ICR7Y29udGV4dE1lc3NhZ2V9JHtvdXRwdXR9JHt0aW1lc3RhbXBEaWZmfVxcbmBcbiAgfVxuXG4gIHByb3RlY3RlZCBzdHJpbmdpZnlNZXNzYWdlIChtZXNzYWdlOiB1bmtub3duLCBsb2dMZXZlbDogTG9nTGV2ZWwpIHtcbiAgICBpZiAoaXNGdW5jdGlvbihtZXNzYWdlKSkge1xuICAgICAgY29uc3QgbWVzc2FnZUFzU3RyID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZSlcbiAgICAgIGNvbnN0IGlzQ2xhc3MgPSBtZXNzYWdlQXNTdHIuc3RhcnRzV2l0aCgnY2xhc3MgJylcbiAgICAgIGlmIChpc0NsYXNzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmluZ2lmeU1lc3NhZ2UoKG1lc3NhZ2UgYXMgRnVuY3Rpb24pLm5hbWUsIGxvZ0xldmVsKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5zdHJpbmdpZnlNZXNzYWdlKG1lc3NhZ2UgYXMgRnVuY3Rpb24sIGxvZ0xldmVsKVxuICAgIH1cblxuICAgIHJldHVybiBpc1BsYWluT2JqZWN0KG1lc3NhZ2UpIHx8IEFycmF5LmlzQXJyYXkobWVzc2FnZSlcbiAgICAgID8gYCR7dGhpcy5jb2xvcml6ZSgnT2JqZWN0OicsIGxvZ0xldmVsKX1cXG4ke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgKGtleSwgdmFsdWUpID0+XG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdiaWdpbnQnID8gdmFsdWUudG9TdHJpbmcoKSA6IHZhbHVlLFxuICAgICAgICAgIDJcbiAgICAgICAgKX1cXG5gXG4gICAgICA6IHRoaXMuY29sb3JpemUobWVzc2FnZSBhcyBzdHJpbmcsIGxvZ0xldmVsKVxuICB9XG5cbiAgcHJvdGVjdGVkIGNvbG9yaXplIChtZXNzYWdlOiBzdHJpbmcsIGxvZ0xldmVsOiBMb2dMZXZlbCkge1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5nZXRDb2xvckJ5TG9nTGV2ZWwobG9nTGV2ZWwpXG4gICAgcmV0dXJuIGNvbG9yKG1lc3NhZ2UpXG4gIH1cblxuICBwcm90ZWN0ZWQgcHJpbnRTdGFja1RyYWNlIChzdGFjazogc3RyaW5nKSB7XG4gICAgaWYgKCFzdGFjaykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGAke3N0YWNrfVxcbmApXG4gIH1cblxuICBwcm90ZWN0ZWQgdXBkYXRlQW5kR2V0VGltZXN0YW1wRGlmZiAoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpbmNsdWRlVGltZXN0YW1wID1cbiAgICAgIENvbnNvbGVMb2dnZXIubGFzdFRpbWVzdGFtcEF0ICYmIHRoaXMub3B0aW9ucz8udGltZXN0YW1wXG4gICAgY29uc3QgcmVzdWx0ID0gaW5jbHVkZVRpbWVzdGFtcFxuICAgICAgPyB0aGlzLmZvcm1hdFRpbWVzdGFtcERpZmYoRGF0ZS5ub3coKSAtIENvbnNvbGVMb2dnZXIubGFzdFRpbWVzdGFtcEF0KVxuICAgICAgOiAnJ1xuICAgIENvbnNvbGVMb2dnZXIubGFzdFRpbWVzdGFtcEF0ID0gRGF0ZS5ub3coKVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIHByb3RlY3RlZCBmb3JtYXRUaW1lc3RhbXBEaWZmICh0aW1lc3RhbXBEaWZmOiBudW1iZXIpIHtcbiAgICByZXR1cm4geWVsbG93KGAgKyR7dGltZXN0YW1wRGlmZn1tc2ApXG4gIH1cblxuICBwcml2YXRlIGdldENvbnRleHRBbmRNZXNzYWdlc1RvUHJpbnQgKGFyZ3M6IHVua25vd25bXSkge1xuICAgIGlmIChhcmdzPy5sZW5ndGggPD0gMSkge1xuICAgICAgcmV0dXJuIHsgbWVzc2FnZXM6IGFyZ3MsIGNvbnRleHQ6IHRoaXMuY29udGV4dCB9XG4gICAgfVxuICAgIGNvbnN0IGxhc3RFbGVtZW50ID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdXG4gICAgY29uc3QgaXNDb250ZXh0ID0gaXNTdHJpbmcobGFzdEVsZW1lbnQpXG4gICAgaWYgKCFpc0NvbnRleHQpIHtcbiAgICAgIHJldHVybiB7IG1lc3NhZ2VzOiBhcmdzLCBjb250ZXh0OiB0aGlzLmNvbnRleHQgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgY29udGV4dDogbGFzdEVsZW1lbnQgYXMgc3RyaW5nLFxuICAgICAgbWVzc2FnZXM6IGFyZ3Muc2xpY2UoMCwgYXJncy5sZW5ndGggLSAxKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29udGV4dEFuZFN0YWNrQW5kTWVzc2FnZXNUb1ByaW50IChhcmdzOiB1bmtub3duW10pIHtcbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHJldHVybiB0aGlzLmlzU3RhY2tGb3JtYXQoYXJnc1sxXSlcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBtZXNzYWdlczogW2FyZ3NbMF1dLFxuICAgICAgICAgICAgc3RhY2s6IGFyZ3NbMV0gYXMgc3RyaW5nLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgICAgfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIG1lc3NhZ2VzOiBbYXJnc1swXV0sXG4gICAgICAgICAgICBjb250ZXh0OiBhcmdzWzFdIGFzIHN0cmluZ1xuICAgICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB7IG1lc3NhZ2VzLCBjb250ZXh0IH0gPSB0aGlzLmdldENvbnRleHRBbmRNZXNzYWdlc1RvUHJpbnQoYXJncylcbiAgICBpZiAobWVzc2FnZXM/Lmxlbmd0aCA8PSAxKSB7XG4gICAgICByZXR1cm4geyBtZXNzYWdlcywgY29udGV4dCB9XG4gICAgfVxuICAgIGNvbnN0IGxhc3RFbGVtZW50ID0gbWVzc2FnZXNbbWVzc2FnZXMubGVuZ3RoIC0gMV1cbiAgICBjb25zdCBpc1N0YWNrID0gaXNTdHJpbmcobGFzdEVsZW1lbnQpXG4gICAgaWYgKCFpc1N0YWNrICYmICFpc1VuZGVmaW5lZChsYXN0RWxlbWVudCkpIHtcbiAgICAgIHJldHVybiB7IG1lc3NhZ2VzLCBjb250ZXh0IH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YWNrOiBsYXN0RWxlbWVudCBhcyBzdHJpbmcsXG4gICAgICBtZXNzYWdlczogbWVzc2FnZXMuc2xpY2UoMCwgbWVzc2FnZXMubGVuZ3RoIC0gMSksXG4gICAgICBjb250ZXh0XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1N0YWNrRm9ybWF0IChzdGFjazogdW5rbm93bikge1xuICAgIGlmICghaXNTdHJpbmcoc3RhY2spICYmICFpc1VuZGVmaW5lZChzdGFjaykpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiAvXiguKStcXG5cXHMrYXQgLis6XFxkKzpcXGQrLy50ZXN0KHN0YWNrKVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2xvckJ5TG9nTGV2ZWwgKGxldmVsOiBMb2dMZXZlbCkge1xuICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgIGNhc2UgJ2RlYnVnJzpcbiAgICAgICAgcmV0dXJuIGNsYy5tYWdlbnRhQnJpZ2h0XG4gICAgICBjYXNlICd3YXJuJzpcbiAgICAgICAgcmV0dXJuIGNsYy55ZWxsb3dcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuIGNsYy5yZWRcbiAgICAgIGNhc2UgJ3ZlcmJvc2UnOlxuICAgICAgICByZXR1cm4gY2xjLmN5YW5CcmlnaHRcbiAgICAgIGNhc2UgJ2ZhdGFsJzpcbiAgICAgICAgcmV0dXJuIGNsYy5ib2xkXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gY2xjLmdyZWVuXG4gICAgfVxuICB9XG59XG4iXX0=