UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

270 lines 36.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StackCollection = exports.CloudAssembly = exports.ExtendedStackSelection = exports.DefaultSelection = void 0; exports.sanitizePatterns = sanitizePatterns; const cxapi = require("@aws-cdk/cx-api"); const chalk = require("chalk"); const minimatch_1 = require("minimatch"); const semver = require("semver"); const logging_1 = require("../../logging"); const error_1 = require("../../toolkit/error"); const util_1 = require("../../util"); var DefaultSelection; (function (DefaultSelection) { /** * Returns an empty selection in case there are no selectors. */ DefaultSelection["None"] = "none"; /** * If the app includes a single stack, returns it. Otherwise throws an exception. * This behavior is used by "deploy". */ DefaultSelection["OnlySingle"] = "single"; /** * Returns all stacks in the main (top level) assembly only. */ DefaultSelection["MainAssembly"] = "main"; /** * If no selectors are provided, returns all stacks in the app, * including stacks inside nested assemblies. */ DefaultSelection["AllStacks"] = "all"; })(DefaultSelection || (exports.DefaultSelection = DefaultSelection = {})); /** * When selecting stacks, what other stacks to include because of dependencies */ var ExtendedStackSelection; (function (ExtendedStackSelection) { /** * Don't select any extra stacks */ ExtendedStackSelection[ExtendedStackSelection["None"] = 0] = "None"; /** * Include stacks that this stack depends on */ ExtendedStackSelection[ExtendedStackSelection["Upstream"] = 1] = "Upstream"; /** * Include stacks that depend on this stack */ ExtendedStackSelection[ExtendedStackSelection["Downstream"] = 2] = "Downstream"; })(ExtendedStackSelection || (exports.ExtendedStackSelection = ExtendedStackSelection = {})); /** * A single Cloud Assembly and the operations we do on it to deploy the artifacts inside */ class CloudAssembly { constructor(assembly) { this.assembly = assembly; this.directory = assembly.directory; } async selectStacks(selector, options) { const asm = this.assembly; const topLevelStacks = asm.stacks; const stacks = semver.major(asm.version) < 10 ? asm.stacks : asm.stacksRecursively; const allTopLevel = selector.allTopLevel ?? false; const patterns = sanitizePatterns(selector.patterns); if (stacks.length === 0) { if (options.ignoreNoStacks) { return new StackCollection(this, []); } throw new error_1.ToolkitError('This app contains no stacks'); } if (allTopLevel) { return this.selectTopLevelStacks(stacks, topLevelStacks, options.extend); } else if (patterns.length > 0) { return this.selectMatchingStacks(stacks, patterns, options.extend); } else { return this.selectDefaultStacks(stacks, topLevelStacks, options.defaultBehavior); } } selectTopLevelStacks(stacks, topLevelStacks, extend = ExtendedStackSelection.None) { if (topLevelStacks.length > 0) { return this.extendStacks(topLevelStacks, stacks, extend); } else { throw new error_1.ToolkitError('No stack found in the main cloud assembly. Use "list" to print manifest'); } } selectMatchingStacks(stacks, patterns, extend = ExtendedStackSelection.None) { const matchingPattern = (pattern) => (stack) => (0, minimatch_1.minimatch)(stack.hierarchicalId, pattern); const matchedStacks = (0, util_1.flatten)(patterns.map(pattern => stacks.filter(matchingPattern(pattern)))); return this.extendStacks(matchedStacks, stacks, extend); } selectDefaultStacks(stacks, topLevelStacks, defaultSelection) { switch (defaultSelection) { case DefaultSelection.MainAssembly: return new StackCollection(this, topLevelStacks); case DefaultSelection.AllStacks: return new StackCollection(this, stacks); case DefaultSelection.None: return new StackCollection(this, []); case DefaultSelection.OnlySingle: if (topLevelStacks.length === 1) { return new StackCollection(this, topLevelStacks); } else { throw new error_1.ToolkitError('Since this app includes more than a single stack, specify which stacks to use (wildcards are supported) or specify `--all`\n' + `Stacks: ${stacks.map(x => x.hierarchicalId).join(' · ')}`); } default: throw new error_1.ToolkitError(`invalid default behavior: ${defaultSelection}`); } } extendStacks(matched, all, extend = ExtendedStackSelection.None) { const allStacks = new Map(); for (const stack of all) { allStacks.set(stack.hierarchicalId, stack); } const index = indexByHierarchicalId(matched); switch (extend) { case ExtendedStackSelection.Downstream: includeDownstreamStacks(index, allStacks); break; case ExtendedStackSelection.Upstream: includeUpstreamStacks(index, allStacks); break; } // Filter original array because it is in the right order const selectedList = all.filter(s => index.has(s.hierarchicalId)); return new StackCollection(this, selectedList); } /** * Select a single stack by its ID */ stackById(stackId) { return new StackCollection(this, [this.assembly.getStackArtifact(stackId)]); } } exports.CloudAssembly = CloudAssembly; /** * A collection of stacks and related artifacts * * In practice, not all artifacts in the CloudAssembly are created equal; * stacks can be selected independently, but other artifacts such as asset * bundles cannot. */ class StackCollection { constructor(assembly, stackArtifacts) { this.assembly = assembly; this.stackArtifacts = stackArtifacts; } get stackCount() { return this.stackArtifacts.length; } get firstStack() { if (this.stackCount < 1) { throw new error_1.ToolkitError('StackCollection contains no stack artifacts (trying to access the first one)'); } return this.stackArtifacts[0]; } get stackIds() { return this.stackArtifacts.map(s => s.id); } get hierarchicalIds() { return this.stackArtifacts.map(s => s.hierarchicalId); } reversed() { const arts = [...this.stackArtifacts]; arts.reverse(); return new StackCollection(this.assembly, arts); } filter(predicate) { return new StackCollection(this.assembly, this.stackArtifacts.filter(predicate)); } concat(...others) { return new StackCollection(this.assembly, this.stackArtifacts.concat(...others.map(o => o.stackArtifacts))); } /** * Extracts 'aws:cdk:warning|info|error' metadata entries from the stack synthesis */ async validateMetadata(failAt = 'error', logger = async () => { }) { let warnings = false; let errors = false; for (const stack of this.stackArtifacts) { for (const message of stack.messages) { switch (message.level) { case cxapi.SynthesisMessageLevel.WARNING: warnings = true; await logger('warn', message); break; case cxapi.SynthesisMessageLevel.ERROR: errors = true; await logger('error', message); break; case cxapi.SynthesisMessageLevel.INFO: await logger('info', message); break; } } } if (errors && failAt != 'none') { throw new error_1.AssemblyError('Found errors'); } if (warnings && failAt === 'warn') { throw new error_1.AssemblyError('Found warnings (--strict mode)'); } } } exports.StackCollection = StackCollection; function indexByHierarchicalId(stacks) { const result = new Map(); for (const stack of stacks) { result.set(stack.hierarchicalId, stack); } return result; } /** * Calculate the transitive closure of stack dependents. * * Modifies `selectedStacks` in-place. */ function includeDownstreamStacks(selectedStacks, allStacks) { const added = new Array(); let madeProgress; do { madeProgress = false; for (const [id, stack] of allStacks) { // Select this stack if it's not selected yet AND it depends on a stack that's in the selected set if (!selectedStacks.has(id) && (stack.dependencies || []).some(dep => selectedStacks.has(dep.id))) { selectedStacks.set(id, stack); added.push(id); madeProgress = true; } } } while (madeProgress); if (added.length > 0) { (0, logging_1.info)('Including depending stacks: %s', chalk.bold(added.join(', '))); } } /** * Calculate the transitive closure of stack dependencies. * * Modifies `selectedStacks` in-place. */ function includeUpstreamStacks(selectedStacks, allStacks) { const added = new Array(); let madeProgress = true; while (madeProgress) { madeProgress = false; for (const stack of selectedStacks.values()) { // Select an additional stack if it's not selected yet and a dependency of a selected stack (and exists, obviously) for (const dependencyId of stack.dependencies.map(x => x.manifest.displayName ?? x.id)) { if (!selectedStacks.has(dependencyId) && allStacks.has(dependencyId)) { added.push(dependencyId); selectedStacks.set(dependencyId, allStacks.get(dependencyId)); madeProgress = true; } } } } if (added.length > 0) { (0, logging_1.info)('Including dependency stacks: %s', chalk.bold(added.join(', '))); } } function sanitizePatterns(patterns) { let sanitized = patterns.filter(s => s != null); // filter null/undefined sanitized = [...new Set(sanitized)]; // make them unique return sanitized; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWQtYXNzZW1ibHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjbG91ZC1hc3NlbWJseS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2WEEsNENBSUM7QUFqWUQseUNBQXlDO0FBQ3pDLCtCQUErQjtBQUMvQix5Q0FBc0M7QUFDdEMsaUNBQWlDO0FBQ2pDLDJDQUFxQztBQUNyQywrQ0FBa0U7QUFDbEUscUNBQXFDO0FBRXJDLElBQVksZ0JBc0JYO0FBdEJELFdBQVksZ0JBQWdCO0lBQzFCOztPQUVHO0lBQ0gsaUNBQWEsQ0FBQTtJQUViOzs7T0FHRztJQUNILHlDQUFxQixDQUFBO0lBRXJCOztPQUVHO0lBQ0gseUNBQXFCLENBQUE7SUFFckI7OztPQUdHO0lBQ0gscUNBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQXRCVyxnQkFBZ0IsZ0NBQWhCLGdCQUFnQixRQXNCM0I7QUFzQkQ7O0dBRUc7QUFDSCxJQUFZLHNCQWVYO0FBZkQsV0FBWSxzQkFBc0I7SUFDaEM7O09BRUc7SUFDSCxtRUFBSSxDQUFBO0lBRUo7O09BRUc7SUFDSCwyRUFBUSxDQUFBO0lBRVI7O09BRUc7SUFDSCwrRUFBVSxDQUFBO0FBQ1osQ0FBQyxFQWZXLHNCQUFzQixzQ0FBdEIsc0JBQXNCLFFBZWpDO0FBa0JEOztHQUVHO0FBQ0gsTUFBYSxhQUFhO0lBTXhCLFlBQTRCLFFBQTZCO1FBQTdCLGFBQVEsR0FBUixRQUFRLENBQXFCO1FBQ3ZELElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztJQUN0QyxDQUFDO0lBRU0sS0FBSyxDQUFDLFlBQVksQ0FBQyxRQUF1QixFQUFFLE9BQTRCO1FBQzdFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDMUIsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztRQUNsQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FB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QyxFQUFFLENBQUM7b0JBQ3JFLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3pCLGNBQWMsQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFFLENBQUMsQ0FBQztvQkFDL0QsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDdEIsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNyQixJQUFBLGNBQUksRUFBQyxpQ0FBaUMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBZ0IsZ0JBQWdCLENBQUMsUUFBa0I7SUFDakQsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLHdCQUF3QjtJQUN6RSxTQUFTLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7SUFDeEQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgeyBtaW5pbWF0Y2ggfSBmcm9tICdtaW5pbWF0Y2gnO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gJ3NlbXZlcic7XG5pbXBvcnQgeyBpbmZvIH0gZnJvbSAnLi4vLi4vbG9nZ2luZyc7XG5pbXBvcnQgeyBBc3NlbWJseUVycm9yLCBUb29sa2l0RXJyb3IgfSBmcm9tICcuLi8uLi90b29sa2l0L2Vycm9yJztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICcuLi8uLi91dGlsJztcblxuZXhwb3J0IGVudW0gRGVmYXVsdFNlbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGVtcHR5IHNlbGVjdGlvbiBpbiBjYXNlIHRoZXJlIGFyZSBubyBzZWxlY3RvcnMuXG4gICAqL1xuICBOb25lID0gJ25vbmUnLFxuXG4gIC8qKlxuICAgKiBJZiB0aGUgYXBwIGluY2x1ZGVzIGEgc2luZ2xlIHN0YWNrLCByZXR1cm5zIGl0LiBPdGhlcndpc2UgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgICogVGhpcyBiZWhhdmlvciBpcyB1c2VkIGJ5IFwiZGVwbG95XCIuXG4gICAqL1xuICBPbmx5U2luZ2xlID0gJ3NpbmdsZScsXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYWxsIHN0YWNrcyBpbiB0aGUgbWFpbiAodG9wIGxldmVsKSBhc3NlbWJseSBvbmx5LlxuICAgKi9cbiAgTWFpbkFzc2VtYmx5ID0gJ21haW4nLFxuXG4gIC8qKlxuICAgKiBJZiBubyBzZWxlY3RvcnMgYXJlIHByb3ZpZGVkLCByZXR1cm5zIGFsbCBzdGFja3MgaW4gdGhlIGFwcCxcbiAgICogaW5jbHVkaW5nIHN0YWNrcyBpbnNpZGUgbmVzdGVkIGFzc2VtYmxpZXMuXG4gICAqL1xuICBBbGxTdGFja3MgPSAnYWxsJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZWxlY3RTdGFja3NPcHRpb25zIHtcbiAgLyoqXG4gICAqIEV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIHVwc3RyZWFkL2Rvd25zdHJlYW0gc3RhY2tzXG4gICAqIEBkZWZhdWx0IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSBvbmx5IHNlbGVjdCB0aGUgc3BlY2lmaWVkIHN0YWNrcy5cbiAgICovXG4gIGV4dGVuZD86IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIFRoZSBiZWhhdmlvciBpZiBubyBzZWxlY3RvcnMgYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGRlcGxveSBpZiB0aGUgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcy5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGlnbm9yZU5vU3RhY2tzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXaGVuIHNlbGVjdGluZyBzdGFja3MsIHdoYXQgb3RoZXIgc3RhY2tzIHRvIGluY2x1ZGUgYmVjYXVzZSBvZiBkZXBlbmRlbmNpZXNcbiAqL1xuZXhwb3J0IGVudW0gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBEb24ndCBzZWxlY3QgYW55IGV4dHJhIHN0YWNrc1xuICAgKi9cbiAgTm9uZSxcblxuICAvKipcbiAgICogSW5jbHVkZSBzdGFja3MgdGhhdCB0aGlzIHN0YWNrIGRlcGVuZHMgb25cbiAgICovXG4gIFVwc3RyZWFtLFxuXG4gIC8qKlxuICAgKiBJbmNsdWRlIHN0YWNrcyB0aGF0IGRlcGVuZCBvbiB0aGlzIHN0YWNrXG4gICAqL1xuICBEb3duc3RyZWFtLFxufVxuXG4vKipcbiAqIEEgc3BlY2lmaWNhdGlvbiBvZiB3aGljaCBzdGFja3Mgc2hvdWxkIGJlIHNlbGVjdGVkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tTZWxlY3RvciB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIGFsbCBzdGFja3MgYXQgdGhlIHRvcCBsZXZlbCBhc3NlbWJseSBzaG91bGRcbiAgICogYmUgc2VsZWN0ZWQgYW5kIG5vdGhpbmcgZWxzZVxuICAgKi9cbiAgYWxsVG9wTGV2ZWw/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgcGF0dGVybnMgdG8gbWF0Y2ggdGhlIHN0YWNrIGhpZXJhcmNoaWNhbCBpZHNcbiAgICovXG4gIHBhdHRlcm5zOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBDbG91ZCBBc3NlbWJseSBhbmQgdGhlIG9wZXJhdGlvbnMgd2UgZG8gb24gaXQgdG8gZGVwbG95IHRoZSBhcnRpZmFjdHMgaW5zaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZEFzc2VtYmx5IHtcbiAgLyoqXG4gICAqIFRoZSBkaXJlY3RvcnkgdGhpcyBDbG91ZEFzc2VtYmx5IHdhcyByZWFkIGZyb21cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkaXJlY3Rvcnk6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgYXNzZW1ibHk6IGN4YXBpLkNsb3VkQXNzZW1ibHkpIHtcbiAgICB0aGlzLmRpcmVjdG9yeSA9IGFzc2VtYmx5LmRpcmVjdG9yeTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZWxlY3RTdGFja3Moc2VsZWN0b3I6IFN0YWNrU2VsZWN0b3IsIG9wdGlvbnM6IFNlbGVjdFN0YWNrc09wdGlvbnMpOiBQcm9taXNlPFN0YWNrQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IGFzbSA9IHRoaXMuYXNzZW1ibHk7XG4gICAgY29uc3QgdG9wTGV2ZWxTdGFja3MgPSBhc20uc3RhY2tzO1xuICAgIGNvbnN0IHN0YWNrcyA9IHNlbXZlci5tYWpvcihhc20udmVyc2lvbikgPCAxMCA/IGFzbS5zdGFja3MgOiBhc20uc3RhY2tzUmVjdXJzaXZlbHk7XG4gICAgY29uc3QgYWxsVG9wTGV2ZWwgPSBzZWxlY3Rvci5hbGxUb3BMZXZlbCA/PyBmYWxzZTtcbiAgICBjb25zdCBwYXR0ZXJucyA9IHNhbml0aXplUGF0dGVybnMoc2VsZWN0b3IucGF0dGVybnMpO1xuXG4gICAgaWYgKHN0YWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvcHRpb25zLmlnbm9yZU5vU3RhY2tzKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIFtdKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycpO1xuICAgIH1cblxuICAgIGlmIChhbGxUb3BMZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0VG9wTGV2ZWxTdGFja3Moc3RhY2tzLCB0b3BMZXZlbFN0YWNrcywgb3B0aW9ucy5leHRlbmQpO1xuICAgIH0gZWxzZSBpZiAocGF0dGVybnMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0TWF0Y2hpbmdTdGFja3Moc3RhY2tzLCBwYXR0ZXJucywgb3B0aW9ucy5leHRlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5zZWxlY3REZWZhdWx0U3RhY2tzKHN0YWNrcywgdG9wTGV2ZWxTdGFja3MsIG9wdGlvbnMuZGVmYXVsdEJlaGF2aW9yKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdFRvcExldmVsU3RhY2tzKFxuICAgIHN0YWNrczogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10sXG4gICAgdG9wTGV2ZWxTdGFja3M6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGV4dGVuZDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiA9IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSxcbiAgKTogU3RhY2tDb2xsZWN0aW9uIHtcbiAgICBpZiAodG9wTGV2ZWxTdGFja3MubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5kU3RhY2tzKHRvcExldmVsU3RhY2tzLCBzdGFja3MsIGV4dGVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ05vIHN0YWNrIGZvdW5kIGluIHRoZSBtYWluIGNsb3VkIGFzc2VtYmx5LiBVc2UgXCJsaXN0XCIgdG8gcHJpbnQgbWFuaWZlc3QnKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VsZWN0TWF0Y2hpbmdTdGFja3MoXG4gICAgc3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBwYXR0ZXJuczogc3RyaW5nW10sXG4gICAgZXh0ZW5kOiBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uID0gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Ob25lLFxuICApOiBTdGFja0NvbGxlY3Rpb24ge1xuXG4gICAgY29uc3QgbWF0Y2hpbmdQYXR0ZXJuID0gKHBhdHRlcm46IHN0cmluZykgPT4gKHN0YWNrOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpID0+IG1pbmltYXRjaChzdGFjay5oaWVyYXJjaGljYWxJZCwgcGF0dGVybik7XG4gICAgY29uc3QgbWF0Y2hlZFN0YWNrcyA9IGZsYXR0ZW4ocGF0dGVybnMubWFwKHBhdHRlcm4gPT4gc3RhY2tzLmZpbHRlcihtYXRjaGluZ1BhdHRlcm4ocGF0dGVybikpKSk7XG5cbiAgICByZXR1cm4gdGhpcy5leHRlbmRTdGFja3MobWF0Y2hlZFN0YWNrcywgc3RhY2tzLCBleHRlbmQpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3REZWZhdWx0U3RhY2tzKFxuICAgIHN0YWNrczogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10sXG4gICAgdG9wTGV2ZWxTdGFja3M6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGRlZmF1bHRTZWxlY3Rpb246IERlZmF1bHRTZWxlY3Rpb24sXG4gICkge1xuICAgIHN3aXRjaCAoZGVmYXVsdFNlbGVjdGlvbikge1xuICAgICAgY2FzZSBEZWZhdWx0U2VsZWN0aW9uLk1haW5Bc3NlbWJseTpcbiAgICAgICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgdG9wTGV2ZWxTdGFja3MpO1xuICAgICAgY2FzZSBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrczpcbiAgICAgICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgc3RhY2tzKTtcbiAgICAgIGNhc2UgRGVmYXVsdFNlbGVjdGlvbi5Ob25lOlxuICAgICAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLCBbXSk7XG4gICAgICBjYXNlIERlZmF1bHRTZWxlY3Rpb24uT25seVNpbmdsZTpcbiAgICAgICAgaWYgKHRvcExldmVsU3RhY2tzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIHRvcExldmVsU3RhY2tzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdTaW5jZSB0aGlzIGFwcCBpbmNsdWRlcyBtb3JlIHRoYW4gYSBzaW5nbGUgc3RhY2ssIHNwZWNpZnkgd2hpY2ggc3RhY2tzIHRvIHVzZSAod2lsZGNhcmRzIGFyZSBzdXBwb3J0ZWQpIG9yIHNwZWNpZnkgYC0tYWxsYFxcbicgK1xuICAgICAgICAgIGBTdGFja3M6ICR7c3RhY2tzLm1hcCh4ID0+IHguaGllcmFyY2hpY2FsSWQpLmpvaW4oJyDCtyAnKX1gKTtcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgaW52YWxpZCBkZWZhdWx0IGJlaGF2aW9yOiAke2RlZmF1bHRTZWxlY3Rpb259YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGV4dGVuZFN0YWNrcyhcbiAgICBtYXRjaGVkOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBhbGw6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGV4dGVuZDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiA9IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSxcbiAgKSB7XG4gICAgY29uc3QgYWxsU3RhY2tzID0gbmV3IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4oKTtcbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIGFsbCkge1xuICAgICAgYWxsU3RhY2tzLnNldChzdGFjay5oaWVyYXJjaGljYWxJZCwgc3RhY2spO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gaW5kZXhCeUhpZXJhcmNoaWNhbElkKG1hdGNoZWQpO1xuXG4gICAgc3dpdGNoIChleHRlbmQpIHtcbiAgICAgIGNhc2UgRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Eb3duc3RyZWFtOlxuICAgICAgICBpbmNsdWRlRG93bnN0cmVhbVN0YWNrcyhpbmRleCwgYWxsU3RhY2tzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uVXBzdHJlYW06XG4gICAgICAgIGluY2x1ZGVVcHN0cmVhbVN0YWNrcyhpbmRleCwgYWxsU3RhY2tzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gRmlsdGVyIG9yaWdpbmFsIGFycmF5IGJlY2F1c2UgaXQgaXMgaW4gdGhlIHJpZ2h0IG9yZGVyXG4gICAgY29uc3Qgc2VsZWN0ZWRMaXN0ID0gYWxsLmZpbHRlcihzID0+IGluZGV4LmhhcyhzLmhpZXJhcmNoaWNhbElkKSk7XG5cbiAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLCBzZWxlY3RlZExpc3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCBhIHNpbmdsZSBzdGFjayBieSBpdHMgSURcbiAgICovXG4gIHB1YmxpYyBzdGFja0J5SWQoc3RhY2tJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgW3RoaXMuYXNzZW1ibHkuZ2V0U3RhY2tBcnRpZmFjdChzdGFja0lkKV0pO1xuICB9XG59XG5cbi8qKlxuICogQSBjb2xsZWN0aW9uIG9mIHN0YWNrcyBhbmQgcmVsYXRlZCBhcnRpZmFjdHNcbiAqXG4gKiBJbiBwcmFjdGljZSwgbm90IGFsbCBhcnRpZmFjdHMgaW4gdGhlIENsb3VkQXNzZW1ibHkgYXJlIGNyZWF0ZWQgZXF1YWw7XG4gKiBzdGFja3MgY2FuIGJlIHNlbGVjdGVkIGluZGVwZW5kZW50bHksIGJ1dCBvdGhlciBhcnRpZmFjdHMgc3VjaCBhcyBhc3NldFxuICogYnVuZGxlcyBjYW5ub3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGFja0NvbGxlY3Rpb24ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgYXNzZW1ibHk6IENsb3VkQXNzZW1ibHksIHB1YmxpYyByZWFkb25seSBzdGFja0FydGlmYWN0czogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10pIHtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc3RhY2tDb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0FydGlmYWN0cy5sZW5ndGg7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZpcnN0U3RhY2soKSB7XG4gICAgaWYgKHRoaXMuc3RhY2tDb3VudCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1N0YWNrQ29sbGVjdGlvbiBjb250YWlucyBubyBzdGFjayBhcnRpZmFjdHMgKHRyeWluZyB0byBhY2Nlc3MgdGhlIGZpcnN0IG9uZSknKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tBcnRpZmFjdHNbMF07XG4gIH1cblxuICBwdWJsaWMgZ2V0IHN0YWNrSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0FydGlmYWN0cy5tYXAocyA9PiBzLmlkKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaGllcmFyY2hpY2FsSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0FydGlmYWN0cy5tYXAocyA9PiBzLmhpZXJhcmNoaWNhbElkKTtcbiAgfVxuXG4gIHB1YmxpYyByZXZlcnNlZCgpIHtcbiAgICBjb25zdCBhcnRzID0gWy4uLnRoaXMuc3RhY2tBcnRpZmFjdHNdO1xuICAgIGFydHMucmV2ZXJzZSgpO1xuICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMuYXNzZW1ibHksIGFydHMpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlcihwcmVkaWNhdGU6IChhcnQ6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCkgPT4gYm9vbGVhbik6IFN0YWNrQ29sbGVjdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcy5hc3NlbWJseSwgdGhpcy5zdGFja0FydGlmYWN0cy5maWx0ZXIocHJlZGljYXRlKSk7XG4gIH1cblxuICBwdWJsaWMgY29uY2F0KC4uLm90aGVyczogU3RhY2tDb2xsZWN0aW9uW10pOiBTdGFja0NvbGxlY3Rpb24ge1xuICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMuYXNzZW1ibHksIHRoaXMuc3RhY2tBcnRpZmFjdHMuY29uY2F0KC4uLm90aGVycy5tYXAobyA9PiBvLnN0YWNrQXJ0aWZhY3RzKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzICdhd3M6Y2RrOndhcm5pbmd8aW5mb3xlcnJvcicgbWV0YWRhdGEgZW50cmllcyBmcm9tIHRoZSBzdGFjayBzeW50aGVzaXNcbiAgICovXG4gIHB1YmxpYyBhc3luYyB2YWxpZGF0ZU1ldGFkYXRhKFxuICAgIGZhaWxBdDogJ3dhcm4nIHwgJ2Vycm9yJyB8ICdub25lJyA9ICdlcnJvcicsXG4gICAgbG9nZ2VyOiAobGV2ZWw6ICdpbmZvJyB8ICdlcnJvcicgfCAnd2FybicsIG1zZzogY3hhcGkuU3ludGhlc2lzTWVzc2FnZSkgPT4gUHJvbWlzZTx2b2lkPiA9IGFzeW5jICgpID0+IHt9LFxuICApIHtcbiAgICBsZXQgd2FybmluZ3MgPSBmYWxzZTtcbiAgICBsZXQgZXJyb3JzID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIHRoaXMuc3RhY2tBcnRpZmFjdHMpIHtcbiAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBzdGFjay5tZXNzYWdlcykge1xuICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UubGV2ZWwpIHtcbiAgICAgICAgICBjYXNlIGN4YXBpLlN5bnRoZXNpc01lc3NhZ2VMZXZlbC5XQVJOSU5HOlxuICAgICAgICAgICAgd2FybmluZ3MgPSB0cnVlO1xuICAgICAgICAgICAgYXdhaXQgbG9nZ2VyKCd3YXJuJywgbWVzc2FnZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGN4YXBpLlN5bnRoZXNpc01lc3NhZ2VMZXZlbC5FUlJPUjpcbiAgICAgICAgICAgIGVycm9ycyA9IHRydWU7XG4gICAgICAgICAgICBhd2FpdCBsb2dnZXIoJ2Vycm9yJywgbWVzc2FnZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGN4YXBpLlN5bnRoZXNpc01lc3NhZ2VMZXZlbC5JTkZPOlxuICAgICAgICAgICAgYXdhaXQgbG9nZ2VyKCdpbmZvJywgbWVzc2FnZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlcnJvcnMgJiYgZmFpbEF0ICE9ICdub25lJykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VtYmx5RXJyb3IoJ0ZvdW5kIGVycm9ycycpO1xuICAgIH1cblxuICAgIGlmICh3YXJuaW5ncyAmJiBmYWlsQXQgPT09ICd3YXJuJykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VtYmx5RXJyb3IoJ0ZvdW5kIHdhcm5pbmdzICgtLXN0cmljdCBtb2RlKScpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1ldGFkYXRhTWVzc2FnZU9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciB0byBiZSB2ZXJib3NlXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICB2ZXJib3NlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRG9uJ3Qgc3RvcCBvbiBlcnJvciBtZXRhZGF0YVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgaWdub3JlRXJyb3JzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVHJlYXQgd2FybmluZ3MgaW4gbWV0YWRhdGEgYXMgZXJyb3JzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBzdHJpY3Q/OiBib29sZWFuO1xufVxuXG5mdW5jdGlvbiBpbmRleEJ5SGllcmFyY2hpY2FsSWQoc3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSk6IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4ge1xuICBjb25zdCByZXN1bHQgPSBuZXcgTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0PigpO1xuXG4gIGZvciAoY29uc3Qgc3RhY2sgb2Ygc3RhY2tzKSB7XG4gICAgcmVzdWx0LnNldChzdGFjay5oaWVyYXJjaGljYWxJZCwgc3RhY2spO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHRyYW5zaXRpdmUgY2xvc3VyZSBvZiBzdGFjayBkZXBlbmRlbnRzLlxuICpcbiAqIE1vZGlmaWVzIGBzZWxlY3RlZFN0YWNrc2AgaW4tcGxhY2UuXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVEb3duc3RyZWFtU3RhY2tzKFxuICBzZWxlY3RlZFN0YWNrczogTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0PixcbiAgYWxsU3RhY2tzOiBNYXA8c3RyaW5nLCBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q+KSB7XG4gIGNvbnN0IGFkZGVkID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICBsZXQgbWFkZVByb2dyZXNzO1xuICBkbyB7XG4gICAgbWFkZVByb2dyZXNzID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IFtpZCwgc3RhY2tdIG9mIGFsbFN0YWNrcykge1xuICAgICAgLy8gU2VsZWN0IHRoaXMgc3RhY2sgaWYgaXQncyBub3Qgc2VsZWN0ZWQgeWV0IEFORCBpdCBkZXBlbmRzIG9uIGEgc3RhY2sgdGhhdCdzIGluIHRoZSBzZWxlY3RlZCBzZXRcbiAgICAgIGlmICghc2VsZWN0ZWRTdGFja3MuaGFzKGlkKSAmJiAoc3RhY2suZGVwZW5kZW5jaWVzIHx8IFtdKS5zb21lKGRlcCA9PiBzZWxlY3RlZFN0YWNrcy5oYXMoZGVwLmlkKSkpIHtcbiAgICAgICAgc2VsZWN0ZWRTdGFja3Muc2V0KGlkLCBzdGFjayk7XG4gICAgICAgIGFkZGVkLnB1c2goaWQpO1xuICAgICAgICBtYWRlUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSB3aGlsZSAobWFkZVByb2dyZXNzKTtcblxuICBpZiAoYWRkZWQubGVuZ3RoID4gMCkge1xuICAgIGluZm8oJ0luY2x1ZGluZyBkZXBlbmRpbmcgc3RhY2tzOiAlcycsIGNoYWxrLmJvbGQoYWRkZWQuam9pbignLCAnKSkpO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSB0cmFuc2l0aXZlIGNsb3N1cmUgb2Ygc3RhY2sgZGVwZW5kZW5jaWVzLlxuICpcbiAqIE1vZGlmaWVzIGBzZWxlY3RlZFN0YWNrc2AgaW4tcGxhY2UuXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVVcHN0cmVhbVN0YWNrcyhcbiAgc2VsZWN0ZWRTdGFja3M6IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4sXG4gIGFsbFN0YWNrczogTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0Pikge1xuICBjb25zdCBhZGRlZCA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG4gIGxldCBtYWRlUHJvZ3Jlc3MgPSB0cnVlO1xuICB3aGlsZSAobWFkZVByb2dyZXNzKSB7XG4gICAgbWFkZVByb2dyZXNzID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIHNlbGVjdGVkU3RhY2tzLnZhbHVlcygpKSB7XG4gICAgICAvLyBTZWxlY3QgYW4gYWRkaXRpb25hbCBzdGFjayBpZiBpdCdzIG5vdCBzZWxlY3RlZCB5ZXQgYW5kIGEgZGVwZW5kZW5jeSBvZiBhIHNlbGVjdGVkIHN0YWNrIChhbmQgZXhpc3RzLCBvYnZpb3VzbHkpXG4gICAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3lJZCBvZiBzdGFjay5kZXBlbmRlbmNpZXMubWFwKHggPT4geC5tYW5pZmVzdC5kaXNwbGF5TmFtZSA/PyB4LmlkKSkge1xuICAgICAgICBpZiAoIXNlbGVjdGVkU3RhY2tzLmhhcyhkZXBlbmRlbmN5SWQpICYmIGFsbFN0YWNrcy5oYXMoZGVwZW5kZW5jeUlkKSkge1xuICAgICAgICAgIGFkZGVkLnB1c2goZGVwZW5kZW5jeUlkKTtcbiAgICAgICAgICBzZWxlY3RlZFN0YWNrcy5zZXQoZGVwZW5kZW5jeUlkLCBhbGxTdGFja3MuZ2V0KGRlcGVuZGVuY3lJZCkhKTtcbiAgICAgICAgICBtYWRlUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGFkZGVkLmxlbmd0aCA+IDApIHtcbiAgICBpbmZvKCdJbmNsdWRpbmcgZGVwZW5kZW5jeSBzdGFja3M6ICVzJywgY2hhbGsuYm9sZChhZGRlZC5qb2luKCcsICcpKSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbml0aXplUGF0dGVybnMocGF0dGVybnM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICBsZXQgc2FuaXRpemVkID0gcGF0dGVybnMuZmlsdGVyKHMgPT4gcyAhPSBudWxsKTsgLy8gZmlsdGVyIG51bGwvdW5kZWZpbmVkXG4gIHNhbml0aXplZCA9IFsuLi5uZXcgU2V0KHNhbml0aXplZCldOyAvLyBtYWtlIHRoZW0gdW5pcXVlXG4gIHJldHVybiBzYW5pdGl6ZWQ7XG59XG4iXX0=