UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

322 lines 37.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Configuration = exports.Command = exports.PROJECT_CONTEXT = void 0; const os = require("os"); const fs_path = require("path"); const toolkit_lib_1 = require("@aws-cdk/toolkit-lib"); const fs = require("fs-extra"); const logging_1 = require("./logging"); const context_1 = require("../api/context"); const settings_1 = require("../api/settings"); exports.PROJECT_CONTEXT = 'cdk.context.json'; const PROJECT_CONFIG = 'cdk.json'; const USER_DEFAULTS = '~/.cdk.json'; const CONTEXT_KEY = 'context'; /** * @deprecated */ var Command; (function (Command) { Command["LS"] = "ls"; Command["LIST"] = "list"; Command["DIFF"] = "diff"; Command["BOOTSTRAP"] = "bootstrap"; Command["DEPLOY"] = "deploy"; Command["DESTROY"] = "destroy"; Command["SYNTHESIZE"] = "synthesize"; Command["SYNTH"] = "synth"; Command["METADATA"] = "metadata"; Command["INIT"] = "init"; Command["VERSION"] = "version"; Command["WATCH"] = "watch"; Command["GC"] = "gc"; Command["ROLLBACK"] = "rollback"; Command["IMPORT"] = "import"; Command["ACKNOWLEDGE"] = "acknowledge"; Command["ACK"] = "ack"; Command["NOTICES"] = "notices"; Command["MIGRATE"] = "migrate"; Command["CONTEXT"] = "context"; Command["DOCS"] = "docs"; Command["DOC"] = "doc"; Command["DOCTOR"] = "doctor"; Command["REFACTOR"] = "refactor"; Command["DRIFT"] = "drift"; Command["CLI_TELEMETRY"] = "cli-telemetry"; })(Command || (exports.Command = Command = {})); const BUNDLING_COMMANDS = [ Command.DEPLOY, Command.DIFF, Command.SYNTH, Command.SYNTHESIZE, Command.WATCH, Command.IMPORT, ]; /** * All sources of settings combined * @deprecated */ class Configuration { constructor(props = {}) { this.props = props; this.settings = new settings_1.Settings(); this.context = new context_1.Context(); this.defaultConfig = new settings_1.Settings({ versionReporting: true, assetMetadata: true, pathMetadata: true, output: 'cdk.out', }); this.loaded = false; this.commandLineArguments = props.commandLineArguments ? commandLineArgumentsToSettings(props.commandLineArguments) : new settings_1.Settings(); this.commandLineContext = this.commandLineArguments .subSettings([CONTEXT_KEY]) .makeReadOnly(); } get projectConfig() { if (!this._projectConfig) { throw new toolkit_lib_1.ToolkitError('#load has not been called yet!'); } return this._projectConfig; } get projectContext() { if (!this._projectContext) { throw new toolkit_lib_1.ToolkitError('#load has not been called yet!'); } return this._projectContext; } /** * Load all config */ async load() { const userConfig = await loadAndLog(USER_DEFAULTS); this._projectConfig = await loadAndLog(PROJECT_CONFIG); this._projectContext = await loadAndLog(exports.PROJECT_CONTEXT); // @todo cannot currently be disabled by cli users const readUserContext = this.props.readUserContext ?? true; if (userConfig.get(['build'])) { throw new toolkit_lib_1.ToolkitError('The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead'); } const contextSources = [ { bag: this.commandLineContext }, { fileName: PROJECT_CONFIG, bag: this.projectConfig.subSettings([CONTEXT_KEY]).makeReadOnly(), }, { fileName: exports.PROJECT_CONTEXT, bag: this.projectContext }, ]; if (readUserContext) { contextSources.push({ fileName: USER_DEFAULTS, bag: userConfig.subSettings([CONTEXT_KEY]).makeReadOnly(), }); } this.context = new context_1.Context(...contextSources); // Build settings from what's left this.settings = this.defaultConfig .merge(userConfig) .merge(this.projectConfig) .merge(this.commandLineArguments) .makeReadOnly(); (0, logging_1.debug)('merged settings:', this.settings.all); this.loaded = true; return this; } /** * Save the project context */ async saveContext() { if (!this.loaded) { return this; } // Avoid overwriting files with nothing await this.projectContext.save(exports.PROJECT_CONTEXT); return this; } } exports.Configuration = Configuration; async function loadAndLog(fileName) { const ret = await settingsFromFile(fileName); if (!ret.empty) { (0, logging_1.debug)(fileName + ':', JSON.stringify(ret.all, undefined, 2)); } return ret; } async function settingsFromFile(fileName) { let settings; const expanded = expandHomeDir(fileName); if (await fs.pathExists(expanded)) { const data = await fs.readJson(expanded); settings = new settings_1.Settings(data); } else { settings = new settings_1.Settings(); } // See https://github.com/aws/aws-cdk/issues/59 prohibitContextKeys(settings, ['default-account', 'default-region'], fileName); warnAboutContextKey(settings, 'aws:', fileName); return settings; } function prohibitContextKeys(settings, keys, fileName) { const context = settings.get(['context']); if (!context || typeof context !== 'object') { return; } for (const key of keys) { if (key in context) { throw new toolkit_lib_1.ToolkitError(`The 'context.${key}' key was found in ${fs_path.resolve(fileName)}, but it is no longer supported. Please remove it.`); } } } function warnAboutContextKey(settings, prefix, fileName) { const context = settings.get(['context']); if (!context || typeof context !== 'object') { return; } for (const contextKey of Object.keys(context)) { if (contextKey.startsWith(prefix)) { (0, logging_1.warning)(`A reserved context key ('context.${prefix}') key was found in ${fs_path.resolve(fileName)}, it might cause surprising behavior and should be removed.`); } } } function expandHomeDir(x) { if (x.startsWith('~')) { return fs_path.join(os.homedir(), x.slice(1)); } return x; } /** * Parse CLI arguments into Settings * * CLI arguments in must be accessed in the CLI code via * `configuration.settings.get(['argName'])` instead of via `args.argName`. * * The advantage is that they can be configured via `cdk.json` and * `$HOME/.cdk.json`. Arguments not listed below and accessed via this object * can only be specified on the command line. * * @param argv - the received CLI arguments. * @returns a new Settings object. */ function commandLineArgumentsToSettings(argv) { const context = parseStringContextListToObject(argv); const tags = parseStringTagsListToObject(expectStringList(argv.tags)); // Determine bundling stacks let bundlingStacks; if (BUNDLING_COMMANDS.includes(argv._[0])) { // If we deploy, diff, synth or watch a list of stacks exclusively we skip // bundling for all other stacks. bundlingStacks = argv.exclusively ? argv.STACKS ?? ['**'] : ['**']; } else { // Skip bundling for all stacks bundlingStacks = []; } return new settings_1.Settings({ app: argv.app, browser: argv.browser, build: argv.build, caBundlePath: argv.caBundlePath, context, debug: argv.debug, tags, language: argv.language, pathMetadata: argv.pathMetadata, assetMetadata: argv.assetMetadata, profile: argv.profile, plugin: argv.plugin, requireApproval: argv.requireApproval, toolkitStackName: argv.toolkitStackName, toolkitBucket: { bucketName: argv.bootstrapBucketName, kmsKeyId: argv.bootstrapKmsKeyId, }, versionReporting: argv.versionReporting, staging: argv.staging, output: argv.output, outputsFile: argv.outputsFile, progress: argv.progress, proxy: argv.proxy, bundlingStacks, lookups: argv.lookups, rollback: argv.rollback, notices: argv.notices, assetParallelism: argv['asset-parallelism'], assetBuildConcurrency: argv['asset-build-concurrency'], assetPrebuild: argv['asset-prebuild'], ignoreNoStacks: argv['ignore-no-stacks'], hotswap: { ecs: { minimumHealthyPercent: argv.hotswapEcsMinimumHealthyPercent, maximumHealthyPercent: argv.hotswapEcsMaximumHealthyPercent, stabilizationTimeoutSeconds: argv.hotswapEcsStabilizationTimeoutSeconds, }, }, unstable: argv.unstable, }); } function expectStringList(x) { if (x === undefined) { return undefined; } if (!Array.isArray(x)) { throw new toolkit_lib_1.ToolkitError(`Expected array, got '${x}'`); } const nonStrings = x.filter((e) => typeof e !== 'string'); if (nonStrings.length > 0) { throw new toolkit_lib_1.ToolkitError(`Expected list of strings, found ${nonStrings}`); } return x; } function parseStringContextListToObject(argv) { const context = {}; for (const assignment of argv.context || []) { const parts = assignment.split(/=(.*)/, 2); if (parts.length === 2) { (0, logging_1.debug)('CLI argument context: %s=%s', parts[0], parts[1]); if (parts[0].match(/^aws:.+/)) { throw new toolkit_lib_1.ToolkitError(`User-provided context cannot use keys prefixed with 'aws:', but ${parts[0]} was provided.`); } context[parts[0]] = parts[1]; } else { (0, logging_1.warning)('Context argument is not an assignment (key=value): %s', assignment); } } return context; } /** * Parse tags out of arguments * * Return undefined if no tags were provided, return an empty array if only empty * strings were provided */ function parseStringTagsListToObject(argTags) { if (argTags === undefined) { return undefined; } if (argTags.length === 0) { return undefined; } const nonEmptyTags = argTags.filter((t) => t !== ''); if (nonEmptyTags.length === 0) { return []; } const tags = []; for (const assignment of nonEmptyTags) { const parts = assignment.split(/=(.*)/, 2); if (parts.length === 2) { (0, logging_1.debug)('CLI argument tags: %s=%s', parts[0], parts[1]); tags.push({ Key: parts[0], Value: parts[1], }); } else { (0, logging_1.warning)('Tags argument is not an assignment (key=value): %s', assignment); } } return tags.length > 0 ? tags : undefined; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvbmZpZ3VyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUJBQXlCO0FBQ3pCLGdDQUFnQztBQUNoQyxzREFBb0Q7QUFDcEQsK0JBQStCO0FBQy9CLHVDQUEyQztBQUMzQyw0Q0FBeUM7QUFDekMsOENBQTJDO0FBRzlCLFFBQUEsZUFBZSxHQUFHLGtCQUFrQixDQUFDO0FBQ2xELE1BQU0sY0FBYyxHQUFHLFVBQVUsQ0FBQztBQUNsQyxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFDcEMsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0FBRTlCOztHQUVHO0FBQ0gsSUFBWSxPQTJCWDtBQTNCRCxXQUFZLE9BQU87SUFDakIsb0JBQVMsQ0FBQTtJQUNULHdCQUFhLENBQUE7SUFDYix3QkFBYSxDQUFBO0lBQ2Isa0NBQXVCLENBQUE7SUFDdkIsNEJBQWlCLENBQUE7SUFDakIsOEJBQW1CLENBQUE7SUFDbkIsb0NBQXlCLENBQUE7SUFDekIsMEJBQWUsQ0FBQTtJQUNmLGdDQUFxQixDQUFBO0lBQ3JCLHdCQUFhLENBQUE7SUFDYiw4QkFBbUIsQ0FBQTtJQUNuQiwwQkFBZSxDQUFBO0lBQ2Ysb0JBQVMsQ0FBQTtJQUNULGdDQUFxQixDQUFBO0lBQ3JCLDRCQUFpQixDQUFBO0lBQ2pCLHNDQUEyQixDQUFBO0lBQzNCLHNCQUFXLENBQUE7SUFDWCw4QkFBbUIsQ0FBQTtJQUNuQiw4QkFBbUIsQ0FBQTtJQUNuQiw4QkFBbUIsQ0FBQTtJQUNuQix3QkFBYSxDQUFBO0lBQ2Isc0JBQVcsQ0FBQTtJQUNYLDRCQUFpQixDQUFBO0lBQ2pCLGdDQUFxQixDQUFBO0lBQ3JCLDBCQUFlLENBQUE7SUFDZiwwQ0FBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBM0JXLE9BQU8sdUJBQVAsT0FBTyxRQTJCbEI7QUFFRCxNQUFNLGlCQUFpQixHQUFHO0lBQ3hCLE9BQU8sQ0FBQyxNQUFN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QUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3JELElBQUksWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM5QixPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxNQUFNLElBQUksR0FBVSxFQUFFLENBQUM7SUFFdkIsS0FBSyxNQUFNLFVBQVUsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN0QyxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkIsSUFBQSxlQUFLLEVBQUMsMEJBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ1IsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2IsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDaEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFBLGlCQUFPLEVBQUMsb0RBQW9ELEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDNUUsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgZnNfcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IFRvb2xraXRFcnJvciB9IGZyb20gJ0Bhd3MtY2RrL3Rvb2xraXQtbGliJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IGRlYnVnLCB3YXJuaW5nIH0gZnJvbSAnLi9sb2dnaW5nJztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9hcGkvY29udGV4dCc7XG5pbXBvcnQgeyBTZXR0aW5ncyB9IGZyb20gJy4uL2FwaS9zZXR0aW5ncyc7XG5pbXBvcnQgdHlwZSB7IFRhZyB9IGZyb20gJy4uL2FwaS90YWdzJztcblxuZXhwb3J0IGNvbnN0IFBST0pFQ1RfQ09OVEVYVCA9ICdjZGsuY29udGV4dC5qc29uJztcbmNvbnN0IFBST0pFQ1RfQ09ORklHID0gJ2Nkay5qc29uJztcbmNvbnN0IFVTRVJfREVGQVVMVFMgPSAnfi8uY2RrLmpzb24nO1xuY29uc3QgQ09OVEVYVF9LRVkgPSAnY29udGV4dCc7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuZXhwb3J0IGVudW0gQ29tbWFuZCB7XG4gIExTID0gJ2xzJyxcbiAgTElTVCA9ICdsaXN0JyxcbiAgRElGRiA9ICdkaWZmJyxcbiAgQk9PVFNUUkFQID0gJ2Jvb3RzdHJhcCcsXG4gIERFUExPWSA9ICdkZXBsb3knLFxuICBERVNUUk9ZID0gJ2Rlc3Ryb3knLFxuICBTWU5USEVTSVpFID0gJ3N5bnRoZXNpemUnLFxuICBTWU5USCA9ICdzeW50aCcsXG4gIE1FVEFEQVRBID0gJ21ldGFkYXRhJyxcbiAgSU5JVCA9ICdpbml0JyxcbiAgVkVSU0lPTiA9ICd2ZXJzaW9uJyxcbiAgV0FUQ0ggPSAnd2F0Y2gnLFxuICBHQyA9ICdnYycsXG4gIFJPTExCQUNLID0gJ3JvbGxiYWNrJyxcbiAgSU1QT1JUID0gJ2ltcG9ydCcsXG4gIEFDS05PV0xFREdFID0gJ2Fja25vd2xlZGdlJyxcbiAgQUNLID0gJ2FjaycsXG4gIE5PVElDRVMgPSAnbm90aWNlcycsXG4gIE1JR1JBVEUgPSAnbWlncmF0ZScsXG4gIENPTlRFWFQgPSAnY29udGV4dCcsXG4gIERPQ1MgPSAnZG9jcycsXG4gIERPQyA9ICdkb2MnLFxuICBET0NUT1IgPSAnZG9jdG9yJyxcbiAgUkVGQUNUT1IgPSAncmVmYWN0b3InLFxuICBEUklGVCA9ICdkcmlmdCcsXG4gIENMSV9URUxFTUVUUlkgPSAnY2xpLXRlbGVtZXRyeScsXG59XG5cbmNvbnN0IEJVTkRMSU5HX0NPTU1BTkRTID0gW1xuICBDb21tYW5kLkRFUExPWSxcbiAgQ29tbWFuZC5ESUZGLFxuICBDb21tYW5kLlNZTlRILFxuICBDb21tYW5kLlNZTlRIRVNJWkUsXG4gIENvbW1hbmQuV0FUQ0gsXG4gIENvbW1hbmQuSU1QT1JULFxuXTtcblxudHlwZSBBcmd1bWVudHMgPSB7XG4gIHJlYWRvbmx5IF86IFtDb21tYW5kLCAuLi5zdHJpbmdbXV07XG4gIHJlYWRvbmx5IGV4Y2x1c2l2ZWx5PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgU1RBQ0tTPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IGxvb2t1cHM/OiBib29sZWFuO1xuICByZWFkb25seSBbbmFtZTogc3RyaW5nXTogdW5rbm93bjtcbn07XG5cbmludGVyZmFjZSBDb25maWd1cmF0aW9uUHJvcHMge1xuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBwYXNzZWQgdmlhIGNvbW1hbmQgbGluZSBhcmd1bWVudHNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb3RoaW5nIHBhc3NlZFxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZExpbmVBcmd1bWVudHM/OiBBcmd1bWVudHM7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRvIHVzZSBjb250ZXh0IGZyb20gYC5jZGsuanNvbmAgaW4gdXNlciBob21lIGRpcmVjdG9yeVxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSByZWFkVXNlckNvbnRleHQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFsbCBzb3VyY2VzIG9mIHNldHRpbmdzIGNvbWJpbmVkXG4gKiBAZGVwcmVjYXRlZFxuICovXG5leHBvcnQgY2xhc3MgQ29uZmlndXJhdGlvbiB7XG4gIHB1YmxpYyBzZXR0aW5ncyA9IG5ldyBTZXR0aW5ncygpO1xuICBwdWJsaWMgY29udGV4dCA9IG5ldyBDb250ZXh0KCk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRDb25maWcgPSBuZXcgU2V0dGluZ3Moe1xuICAgIHZlcnNpb25SZXBvcnRpbmc6IHRydWUsXG4gICAgYXNzZXRNZXRhZGF0YTogdHJ1ZSxcbiAgICBwYXRoTWV0YWRhdGE6IHRydWUsXG4gICAgb3V0cHV0OiAnY2RrLm91dCcsXG4gIH0pO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZExpbmVBcmd1bWVudHM6IFNldHRpbmdzO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRMaW5lQ29udGV4dDogU2V0dGluZ3M7XG4gIHByaXZhdGUgX3Byb2plY3RDb25maWc/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBfcHJvamVjdENvbnRleHQ/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBsb2FkZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBDb25maWd1cmF0aW9uUHJvcHMgPSB7fSkge1xuICAgIHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHMgPSBwcm9wcy5jb21tYW5kTGluZUFyZ3VtZW50c1xuICAgICAgPyBjb21tYW5kTGluZUFyZ3VtZW50c1RvU2V0dGluZ3MocHJvcHMuY29tbWFuZExpbmVBcmd1bWVudHMpXG4gICAgICA6IG5ldyBTZXR0aW5ncygpO1xuICAgIHRoaXMuY29tbWFuZExpbmVDb250ZXh0ID0gdGhpcy5jb21tYW5kTGluZUFyZ3VtZW50c1xuICAgICAgLnN1YlNldHRpbmdzKFtDT05URVhUX0tFWV0pXG4gICAgICAubWFrZVJlYWRPbmx5KCk7XG4gIH1cblxuICBwcml2YXRlIGdldCBwcm9qZWN0Q29uZmlnKCkge1xuICAgIGlmICghdGhpcy5fcHJvamVjdENvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignI2xvYWQgaGFzIG5vdCBiZWVuIGNhbGxlZCB5ZXQhJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9wcm9qZWN0Q29uZmlnO1xuICB9XG5cbiAgcHVibGljIGdldCBwcm9qZWN0Q29udGV4dCgpIHtcbiAgICBpZiAoIXRoaXMuX3Byb2plY3RDb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCcjbG9hZCBoYXMgbm90IGJlZW4gY2FsbGVkIHlldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Byb2plY3RDb250ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYWxsIGNvbmZpZ1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGxvYWQoKTogUHJvbWlzZTx0aGlzPiB7XG4gICAgY29uc3QgdXNlckNvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2coVVNFUl9ERUZBVUxUUyk7XG4gICAgdGhpcy5fcHJvamVjdENvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2coUFJPSkVDVF9DT05GSUcpO1xuICAgIHRoaXMuX3Byb2plY3RDb250ZXh0ID0gYXdhaXQgbG9hZEFuZExvZyhQUk9KRUNUX0NPTlRFWFQpO1xuXG4gICAgLy8gQHRvZG8gY2Fubm90IGN1cnJlbnRseSBiZSBkaXNhYmxlZCBieSBjbGkgdXNlcnNcbiAgICBjb25zdCByZWFkVXNlckNvbnRleHQgPSB0aGlzLnByb3BzLnJlYWRVc2VyQ29udGV4dCA/PyB0cnVlO1xuXG4gICAgaWYgKHVzZXJDb25maWcuZ2V0KFsnYnVpbGQnXSkpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdUaGUgYGJ1aWxkYCBrZXkgY2Fubm90IGJlIHNwZWNpZmllZCBpbiB0aGUgdXNlciBjb25maWcgKH4vLmNkay5qc29uKSwgc3BlY2lmeSBpdCBpbiB0aGUgcHJvamVjdCBjb25maWcgKGNkay5qc29uKSBpbnN0ZWFkJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dFNvdXJjZXMgPSBbXG4gICAgICB7IGJhZzogdGhpcy5jb21tYW5kTGluZUNvbnRleHQgfSxcbiAgICAgIHtcbiAgICAgICAgZmlsZU5hbWU6IFBST0pFQ1RfQ09ORklHLFxuICAgICAgICBiYWc6IHRoaXMucHJvamVjdENvbmZpZy5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKS5tYWtlUmVhZE9ubHkoKSxcbiAgICAgIH0sXG4gICAgICB7IGZpbGVOYW1lOiBQUk9KRUNUX0NPTlRFWFQsIGJhZzogdGhpcy5wcm9qZWN0Q29udGV4dCB9LFxuICAgIF07XG4gICAgaWYgKHJlYWRVc2VyQ29udGV4dCkge1xuICAgICAgY29udGV4dFNvdXJjZXMucHVzaCh7XG4gICAgICAgIGZpbGVOYW1lOiBVU0VSX0RFRkFVTFRTLFxuICAgICAgICBiYWc6IHVzZXJDb25maWcuc3ViU2V0dGluZ3MoW0NPTlRFWFRfS0VZXSkubWFrZVJlYWRPbmx5KCksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dCguLi5jb250ZXh0U291cmNlcyk7XG5cbiAgICAvLyBCdWlsZCBzZXR0aW5ncyBmcm9tIHdoYXQncyBsZWZ0XG4gICAgdGhpcy5zZXR0aW5ncyA9IHRoaXMuZGVmYXVsdENvbmZpZ1xuICAgICAgLm1lcmdlKHVzZXJDb25maWcpXG4gICAgICAubWVyZ2UodGhpcy5wcm9qZWN0Q29uZmlnKVxuICAgICAgLm1lcmdlKHRoaXMuY29tbWFuZExpbmVBcmd1bWVudHMpXG4gICAgICAubWFrZVJlYWRPbmx5KCk7XG5cbiAgICBkZWJ1ZygnbWVyZ2VkIHNldHRpbmdzOicsIHRoaXMuc2V0dGluZ3MuYWxsKTtcblxuICAgIHRoaXMubG9hZGVkID0gdHJ1ZTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmUgdGhlIHByb2plY3QgY29udGV4dFxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNhdmVDb250ZXh0KCk6IFByb21pc2U8dGhpcz4ge1xuICAgIGlmICghdGhpcy5sb2FkZWQpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0gLy8gQXZvaWQgb3ZlcndyaXRpbmcgZmlsZXMgd2l0aCBub3RoaW5nXG5cbiAgICBhd2FpdCB0aGlzLnByb2plY3RDb250ZXh0LnNhdmUoUFJPSkVDVF9DT05URVhUKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxvYWRBbmRMb2coZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgY29uc3QgcmV0ID0gYXdhaXQgc2V0dGluZ3NGcm9tRmlsZShmaWxlTmFtZSk7XG4gIGlmICghcmV0LmVtcHR5KSB7XG4gICAgZGVidWcoZmlsZU5hbWUgKyAnOicsIEpTT04uc3RyaW5naWZ5KHJldC5hbGwsIHVuZGVmaW5lZCwgMikpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNldHRpbmdzRnJvbUZpbGUoZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgbGV0IHNldHRpbmdzO1xuICBjb25zdCBleHBhbmRlZCA9IGV4cGFuZEhvbWVEaXIoZmlsZU5hbWUpO1xuICBpZiAoYXdhaXQgZnMucGF0aEV4aXN0cyhleHBhbmRlZCkpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgZnMucmVhZEpzb24oZXhwYW5kZWQpO1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKGRhdGEpO1xuICB9IGVsc2Uge1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKCk7XG4gIH1cblxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy81OVxuICBwcm9oaWJpdENvbnRleHRLZXlzKHNldHRpbmdzLCBbJ2RlZmF1bHQtYWNjb3VudCcsICdkZWZhdWx0LXJlZ2lvbiddLCBmaWxlTmFtZSk7XG4gIHdhcm5BYm91dENvbnRleHRLZXkoc2V0dGluZ3MsICdhd3M6JywgZmlsZU5hbWUpO1xuXG4gIHJldHVybiBzZXR0aW5ncztcbn1cblxuZnVuY3Rpb24gcHJvaGliaXRDb250ZXh0S2V5cyhzZXR0aW5nczogU2V0dGluZ3MsIGtleXM6IHN0cmluZ1tdLCBmaWxlTmFtZTogc3RyaW5nKSB7XG4gIGNvbnN0IGNvbnRleHQgPSBzZXR0aW5ncy5nZXQoWydjb250ZXh0J10pO1xuICBpZiAoIWNvbnRleHQgfHwgdHlwZW9mIGNvbnRleHQgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgIGlmIChrZXkgaW4gY29udGV4dCkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihcbiAgICAgICAgYFRoZSAnY29udGV4dC4ke2tleX0nIGtleSB3YXMgZm91bmQgaW4gJHtmc19wYXRoLnJlc29sdmUoXG4gICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICl9LCBidXQgaXQgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC4gUGxlYXNlIHJlbW92ZSBpdC5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gd2FybkFib3V0Q29udGV4dEtleShzZXR0aW5nczogU2V0dGluZ3MsIHByZWZpeDogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nKSB7XG4gIGNvbnN0IGNvbnRleHQgPSBzZXR0aW5ncy5nZXQoWydjb250ZXh0J10pO1xuICBpZiAoIWNvbnRleHQgfHwgdHlwZW9mIGNvbnRleHQgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yIChjb25zdCBjb250ZXh0S2V5IG9mIE9iamVjdC5rZXlzKGNvbnRleHQpKSB7XG4gICAgaWYgKGNvbnRleHRLZXkuc3RhcnRzV2l0aChwcmVmaXgpKSB7XG4gICAgICB3YXJuaW5nKFxuICAgICAgICBgQSByZXNlcnZlZCBjb250ZXh0IGtleSAoJ2NvbnRleHQuJHtwcmVmaXh9Jykga2V5IHdhcyBmb3VuZCBpbiAke2ZzX3BhdGgucmVzb2x2ZShcbiAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgKX0sIGl0IG1pZ2h0IGNhdXNlIHN1cnByaXNpbmcgYmVoYXZpb3IgYW5kIHNob3VsZCBiZSByZW1vdmVkLmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBleHBhbmRIb21lRGlyKHg6IHN0cmluZykge1xuICBpZiAoeC5zdGFydHNXaXRoKCd+JykpIHtcbiAgICByZXR1cm4gZnNfcGF0aC5qb2luKG9zLmhvbWVkaXIoKSwgeC5zbGljZSgxKSk7XG4gIH1cbiAgcmV0dXJuIHg7XG59XG5cbi8qKlxuICogUGFyc2UgQ0xJIGFyZ3VtZW50cyBpbnRvIFNldHRpbmdzXG4gKlxuICogQ0xJIGFyZ3VtZW50cyBpbiBtdXN0IGJlIGFjY2Vzc2VkIGluIHRoZSBDTEkgY29kZSB2aWFcbiAqIGBjb25maWd1cmF0aW9uLnNldHRpbmdzLmdldChbJ2FyZ05hbWUnXSlgIGluc3RlYWQgb2YgdmlhIGBhcmdzLmFyZ05hbWVgLlxuICpcbiAqIFRoZSBhZHZhbnRhZ2UgaXMgdGhhdCB0aGV5IGNhbiBiZSBjb25maWd1cmVkIHZpYSBgY2RrLmpzb25gIGFuZFxuICogYCRIT01FLy5jZGsuanNvbmAuIEFyZ3VtZW50cyBub3QgbGlzdGVkIGJlbG93IGFuZCBhY2Nlc3NlZCB2aWEgdGhpcyBvYmplY3RcbiAqIGNhbiBvbmx5IGJlIHNwZWNpZmllZCBvbiB0aGUgY29tbWFuZCBsaW5lLlxuICpcbiAqIEBwYXJhbSBhcmd2IC0gdGhlIHJlY2VpdmVkIENMSSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIG5ldyBTZXR0aW5ncyBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGNvbW1hbmRMaW5lQXJndW1lbnRzVG9TZXR0aW5ncyhhcmd2OiBBcmd1bWVudHMpOiBTZXR0aW5ncyB7XG4gIGNvbnN0IGNvbnRleHQgPSBwYXJzZVN0cmluZ0NvbnRleHRMaXN0VG9PYmplY3QoYXJndik7XG4gIGNvbnN0IHRhZ3MgPSBwYXJzZVN0cmluZ1RhZ3NMaXN0VG9PYmplY3QoZXhwZWN0U3RyaW5nTGlzdChhcmd2LnRhZ3MpKTtcblxuICAvLyBEZXRlcm1pbmUgYnVuZGxpbmcgc3RhY2tzXG4gIGxldCBidW5kbGluZ1N0YWNrczogc3RyaW5nW107XG4gIGlmIChCVU5ETElOR19DT01NQU5EUy5pbmNsdWRlcyhhcmd2Ll9bMF0pKSB7XG4gICAgLy8gSWYgd2UgZGVwbG95LCBkaWZmLCBzeW50aCBvciB3YXRjaCBhIGxpc3Qgb2Ygc3RhY2tzIGV4Y2x1c2l2ZWx5IHdlIHNraXBcbiAgICAvLyBidW5kbGluZyBmb3IgYWxsIG90aGVyIHN0YWNrcy5cbiAgICBidW5kbGluZ1N0YWNrcyA9IGFyZ3YuZXhjbHVzaXZlbHkgPyBhcmd2LlNUQUNLUyA/PyBbJyoqJ10gOiBbJyoqJ107XG4gIH0gZWxzZSB7XG4gICAgLy8gU2tpcCBidW5kbGluZyBmb3IgYWxsIHN0YWNrc1xuICAgIGJ1bmRsaW5nU3RhY2tzID0gW107XG4gIH1cblxuICByZXR1cm4gbmV3IFNldHRpbmdzKHtcbiAgICBhcHA6IGFyZ3YuYXBwLFxuICAgIGJyb3dzZXI6IGFyZ3YuYnJvd3NlcixcbiAgICBidWlsZDogYXJndi5idWlsZCxcbiAgICBjYUJ1bmRsZVBhdGg6IGFyZ3YuY2FCdW5kbGVQYXRoLFxuICAgIGNvbnRleHQsXG4gICAgZGVidWc6IGFyZ3YuZGVidWcsXG4gICAgdGFncyxcbiAgICBsYW5ndWFnZTogYXJndi5sYW5ndWFnZSxcbiAgICBwYXRoTWV0YWRhdGE6IGFyZ3YucGF0aE1ldGFkYXRhLFxuICAgIGFzc2V0TWV0YWRhdGE6IGFyZ3YuYXNzZXRNZXRhZGF0YSxcbiAgICBwcm9maWxlOiBhcmd2LnByb2ZpbGUsXG4gICAgcGx1Z2luOiBhcmd2LnBsdWdpbixcbiAgICByZXF1aXJlQXBwcm92YWw6IGFyZ3YucmVxdWlyZUFwcHJvdmFsLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGFyZ3YudG9vbGtpdFN0YWNrTmFtZSxcbiAgICB0b29sa2l0QnVja2V0OiB7XG4gICAgICBidWNrZXROYW1lOiBhcmd2LmJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gICAgICBrbXNLZXlJZDogYXJndi5ib290c3RyYXBLbXNLZXlJZCxcbiAgICB9LFxuICAgIHZlcnNpb25SZXBvcnRpbmc6IGFyZ3YudmVyc2lvblJlcG9ydGluZyxcbiAgICBzdGFnaW5nOiBhcmd2LnN0YWdpbmcsXG4gICAgb3V0cHV0OiBhcmd2Lm91dHB1dCxcbiAgICBvdXRwdXRzRmlsZTogYXJndi5vdXRwdXRzRmlsZSxcbiAgICBwcm9ncmVzczogYXJndi5wcm9ncmVzcyxcbiAgICBwcm94eTogYXJndi5wcm94eSxcbiAgICBidW5kbGluZ1N0YWNrcyxcbiAgICBsb29rdXBzOiBhcmd2Lmxvb2t1cHMsXG4gICAgcm9sbGJhY2s6IGFyZ3Yucm9sbGJhY2ssXG4gICAgbm90aWNlczogYXJndi5ub3RpY2VzLFxuICAgIGFzc2V0UGFyYWxsZWxpc206IGFyZ3ZbJ2Fzc2V0LXBhcmFsbGVsaXNtJ10sXG4gICAgYXNzZXRCdWlsZENvbmN1cnJlbmN5OiBhcmd2Wydhc3NldC1idWlsZC1jb25jdXJyZW5jeSddLFxuICAgIGFzc2V0UHJlYnVpbGQ6IGFyZ3ZbJ2Fzc2V0LXByZWJ1aWxkJ10sXG4gICAgaWdub3JlTm9TdGFja3M6IGFyZ3ZbJ2lnbm9yZS1uby1zdGFja3MnXSxcbiAgICBob3Rzd2FwOiB7XG4gICAgICBlY3M6IHtcbiAgICAgICAgbWluaW11bUhlYWx0aHlQZXJjZW50OiBhcmd2LmhvdHN3YXBFY3NNaW5pbXVtSGVhbHRoeVBlcmNlbnQsXG4gICAgICAgIG1heGltdW1IZWFsdGh5UGVyY2VudDogYXJndi5ob3Rzd2FwRWNzTWF4aW11bUhlYWx0aHlQZXJjZW50LFxuICAgICAgICBzdGFiaWxpemF0aW9uVGltZW91dFNlY29uZHM6IGFyZ3YuaG90c3dhcEVjc1N0YWJpbGl6YXRpb25UaW1lb3V0U2Vjb25kcyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB1bnN0YWJsZTogYXJndi51bnN0YWJsZSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGV4cGVjdFN0cmluZ0xpc3QoeDogdW5rbm93bik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgRXhwZWN0ZWQgYXJyYXksIGdvdCAnJHt4fSdgKTtcbiAgfVxuICBjb25zdCBub25TdHJpbmdzID0geC5maWx0ZXIoKGUpID0+IHR5cGVvZiBlICE9PSAnc3RyaW5nJyk7XG4gIGlmIChub25TdHJpbmdzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGBFeHBlY3RlZCBsaXN0IG9mIHN0cmluZ3MsIGZvdW5kICR7bm9uU3RyaW5nc31gKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGFyZ3Y6IEFyZ3VtZW50cyk6IGFueSB7XG4gIGNvbnN0IGNvbnRleHQ6IGFueSA9IHt9O1xuXG4gIGZvciAoY29uc3QgYXNzaWdubWVudCBvZiAoYXJndiBhcyBhbnkpLmNvbnRleHQgfHwgW10pIHtcbiAgICBjb25zdCBwYXJ0cyA9IGFzc2lnbm1lbnQuc3BsaXQoLz0oLiopLywgMik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgZGVidWcoJ0NMSSBhcmd1bWVudCBjb250ZXh0OiAlcz0lcycsIHBhcnRzWzBdLCBwYXJ0c1sxXSk7XG4gICAgICBpZiAocGFydHNbMF0ubWF0Y2goL15hd3M6LisvKSkge1xuICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKFxuICAgICAgICAgIGBVc2VyLXByb3ZpZGVkIGNvbnRleHQgY2Fubm90IHVzZSBrZXlzIHByZWZpeGVkIHdpdGggJ2F3czonLCBidXQgJHtwYXJ0c1swXX0gd2FzIHByb3ZpZGVkLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb250ZXh0W3BhcnRzWzBdXSA9IHBhcnRzWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICB3YXJuaW5nKFxuICAgICAgICAnQ29udGV4dCBhcmd1bWVudCBpcyBub3QgYW4gYXNzaWdubWVudCAoa2V5PXZhbHVlKTogJXMnLFxuICAgICAgICBhc3NpZ25tZW50LFxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbi8qKlxuICogUGFyc2UgdGFncyBvdXQgb2YgYXJndW1lbnRzXG4gKlxuICogUmV0dXJuIHVuZGVmaW5lZCBpZiBubyB0YWdzIHdlcmUgcHJvdmlkZWQsIHJldHVybiBhbiBlbXB0eSBhcnJheSBpZiBvbmx5IGVtcHR5XG4gKiBzdHJpbmdzIHdlcmUgcHJvdmlkZWRcbiAqL1xuZnVuY3Rpb24gcGFyc2VTdHJpbmdUYWdzTGlzdFRvT2JqZWN0KFxuICBhcmdUYWdzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCxcbik6IFRhZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKGFyZ1RhZ3MgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKGFyZ1RhZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBub25FbXB0eVRhZ3MgPSBhcmdUYWdzLmZpbHRlcigodCkgPT4gdCAhPT0gJycpO1xuICBpZiAobm9uRW1wdHlUYWdzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHRhZ3M6IFRhZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCBhc3NpZ25tZW50IG9mIG5vbkVtcHR5VGFncykge1xuICAgIGNvbnN0IHBhcnRzID0gYXNzaWdubWVudC5zcGxpdCgvPSguKikvLCAyKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBkZWJ1ZygnQ0xJIGFyZ3VtZW50IHRhZ3M6ICVzPSVzJywgcGFydHNbMF0sIHBhcnRzWzFdKTtcbiAgICAgIHRhZ3MucHVzaCh7XG4gICAgICAgIEtleTogcGFydHNbMF0sXG4gICAgICAgIFZhbHVlOiBwYXJ0c1sxXSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB3YXJuaW5nKCdUYWdzIGFyZ3VtZW50IGlzIG5vdCBhbiBhc3NpZ25tZW50IChrZXk9dmFsdWUpOiAlcycsIGFzc2lnbm1lbnQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGFncy5sZW5ndGggPiAwID8gdGFncyA6IHVuZGVmaW5lZDtcbn1cbiJdfQ==