aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
143 lines • 18.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateSourceOptions = exports.setEnvironment = exports.readFromStack = exports.readFromPath = exports.generateStack = exports.generateCdkApp = exports.MIGRATE_SUPPORTED_LANGUAGES = void 0;
/* eslint-disable @typescript-eslint/no-require-imports */
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require("fs");
const path = require("path");
const cx_api_1 = require("@aws-cdk/cx-api");
const cdk_from_cfn = require("cdk-from-cfn");
const init_1 = require("../../lib/init");
const api_1 = require("../api");
const archive_1 = require("../util/archive");
const camelCase = require('camelcase');
const decamelize = require('decamelize');
/** The list of languages supported by the built-in noctilucent binary. */
exports.MIGRATE_SUPPORTED_LANGUAGES = cdk_from_cfn.supported_languages();
/**
* Generates a CDK app from a yaml or json template.
*
* @param stackName The name to assign to the stack in the generated app
* @param stack The yaml or json template for the stack
* @param language The language to generate the CDK app in
* @param outputPath The path at which to generate the CDK app
*/
async function generateCdkApp(stackName, stack, language, outputPath, compress) {
const resolvedOutputPath = path.join(outputPath ?? process.cwd(), stackName);
const formattedStackName = decamelize(stackName);
try {
fs.rmSync(resolvedOutputPath, { recursive: true, force: true });
fs.mkdirSync(resolvedOutputPath, { recursive: true });
const generateOnly = compress;
await (0, init_1.cliInit)({
type: 'app',
language,
canUseNetwork: true,
generateOnly,
workDir: resolvedOutputPath,
stackName,
});
let stackFileName;
switch (language) {
case 'typescript':
stackFileName = `${resolvedOutputPath}/lib/${formattedStackName}-stack.ts`;
break;
case 'java':
stackFileName = `${resolvedOutputPath}/src/main/java/com/myorg/${camelCase(formattedStackName, { pascalCase: true })}Stack.java`;
break;
case 'python':
stackFileName = `${resolvedOutputPath}/${formattedStackName.replace(/-/g, '_')}/${formattedStackName.replace(/-/g, '_')}_stack.py`;
break;
case 'csharp':
stackFileName = `${resolvedOutputPath}/src/${camelCase(formattedStackName, { pascalCase: true })}/${camelCase(formattedStackName, { pascalCase: true })}Stack.cs`;
break;
case 'go':
stackFileName = `${resolvedOutputPath}/${formattedStackName}.go`;
break;
default:
throw new Error(`${language} is not supported by CDK Migrate. Please choose from: ${exports.MIGRATE_SUPPORTED_LANGUAGES.join(', ')}`);
}
fs.writeFileSync(stackFileName, stack);
if (compress) {
await (0, archive_1.zipDirectory)(resolvedOutputPath, `${resolvedOutputPath}.zip`);
fs.rmSync(resolvedOutputPath, { recursive: true, force: true });
}
}
catch (error) {
fs.rmSync(resolvedOutputPath, { recursive: true, force: true });
throw error;
}
}
exports.generateCdkApp = generateCdkApp;
/**
* Generates a CDK stack file.
* @param template The template to translate into a CDK stack
* @param stackName The name to assign to the stack
* @param language The language to generate the stack in
* @returns A string representation of a CDK stack file
*/
function generateStack(template, stackName, language) {
try {
const formattedStackName = `${camelCase(decamelize(stackName), { pascalCase: true })}Stack`;
return cdk_from_cfn.transmute(template, language, formattedStackName);
}
catch (e) {
throw new Error(`stack generation failed due to error '${e.message}'`);
}
}
exports.generateStack = generateStack;
/**
* Reads and returns a stack template from a local path.
*
* @param inputPath The location of the template
* @returns A string representation of the template if present, otherwise undefined
*/
function readFromPath(inputPath) {
try {
return inputPath ? fs.readFileSync(inputPath, 'utf8') : undefined;
}
catch (e) {
throw new Error(`'${inputPath}' is not a valid path.`);
}
}
exports.readFromPath = readFromPath;
/**
* Reads and returns a stack template from a deployed CloudFormation stack.
*
* @param stackName The name of the stack
* @param sdkProvider The sdk provider for making CloudFormation calls
* @param environment The account and region where the stack is deployed
* @returns A string representation of the template if present, otherwise undefined
*/
async function readFromStack(stackName, sdkProvider, environment) {
const cloudFormation = (await sdkProvider.forEnvironment(environment, api_1.Mode.ForReading)).sdk.cloudFormation();
return (await cloudFormation.getTemplate({
StackName: stackName,
}).promise()).TemplateBody;
}
exports.readFromStack = readFromStack;
/**
* Sets the account and region for making CloudFormation calls.
* @param account The account to use
* @param region The region to use
* @returns The environment object
*/
function setEnvironment(account, region) {
return { account: account ?? cx_api_1.UNKNOWN_ACCOUNT, region: region ?? cx_api_1.UNKNOWN_REGION, name: 'cdk-migrate-env' };
}
exports.setEnvironment = setEnvironment;
/**
* Validates that exactly one source option has been provided.
* @param fromPath The content of the flag `--from-path`
* @param fromStack the content of the flag `--from-stack`
*/
function validateSourceOptions(fromPath, fromStack) {
if (fromPath && fromStack) {
throw new Error('Only one of `--from-path` or `--from-stack` may be provided.');
}
if (!fromPath && !fromStack) {
throw new Error('Either `--from-path` or `--from-stack` must be used to provide the source of the CloudFormation template.');
}
}
exports.validateSourceOptions = validateSourceOptions;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1pZ3JhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMERBQTBEO0FBQzFELHVEQUF1RDtBQUN2RCx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLDRDQUErRTtBQUMvRSw2Q0FBNkM7QUFDN0MseUNBQXlDO0FBQ3pDLGdDQUEyQztBQUMzQyw2Q0FBK0M7QUFFL0MsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3ZDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUV6QywwRUFBMEU7QUFDN0QsUUFBQSwyQkFBMkIsR0FBc0IsWUFBWSxDQUFDLG1CQUFtQixFQUFFLENBQUM7QUFFakc7Ozs7Ozs7R0FPRztBQUNJLEtBQUssVUFBVSxjQUFjLENBQUMsU0FBaUIsRUFBRSxLQUFhLEVBQUUsUUFBZ0IsRUFBRSxVQUFtQixFQUFFLFFBQWtCO0lBQzlILE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzdFLE1BQU0sa0JBQWtCLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRWpELElBQUk7UUFDRixFQUFFLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRSxFQUFFLENBQUMsU0FBUyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdEQsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDO1FBQzlCLE1BQU0sSUFBQSxjQUFPLEVBQUM7WUFDWixJQUFJLEVBQUUsS0FBSztZQUNYLFFBQVE7WUFDUixhQUFhLEVBQUUsSUFBSTtZQUNuQixZQUFZO1lB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RUgsQ0FBQztBQVBELG9DQU9DO0FBRUQ7Ozs7Ozs7R0FPRztBQUNJLEtBQUssVUFBVSxhQUFhLENBQUMsU0FBaUIsRUFBRSxXQUF3QixFQUFFLFdBQXdCO0lBQ3ZHLE1BQU0sY0FBYyxHQUFHLENBQUMsTUFBTSxXQUFXLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxVQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUM7SUFFN0csT0FBTyxDQUFDLE1BQU0sY0FBYyxDQUFDLFdBQVcsQ0FBQztRQUN2QyxTQUFTLEVBQUUsU0FBUztLQUNyQixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUM7QUFDN0IsQ0FBQztBQU5ELHNDQU1DO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixjQUFjLENBQUMsT0FBZ0IsRUFBRSxNQUFlO0lBQzlELE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxJQUFJLHdCQUFlLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSx1QkFBYyxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxDQUFDO0FBQzVHLENBQUM7QUFGRCx3Q0FFQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixxQkFBcUIsQ0FBQyxRQUFpQixFQUFFLFNBQW1CO0lBQzFFLElBQUksUUFBUSxJQUFJLFNBQVMsRUFBRTtRQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUM7S0FDakY7SUFFRCxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsU0FBUyxFQUFFO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsMkdBQTJHLENBQUMsQ0FBQztLQUM5SDtBQUNILENBQUM7QUFSRCxzREFRQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMgKi9cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBFbnZpcm9ubWVudCwgVU5LTk9XTl9BQ0NPVU5ULCBVTktOT1dOX1JFR0lPTiB9IGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBjZGtfZnJvbV9jZm4gZnJvbSAnY2RrLWZyb20tY2ZuJztcbmltcG9ydCB7IGNsaUluaXQgfSBmcm9tICcuLi8uLi9saWIvaW5pdCc7XG5pbXBvcnQgeyBNb2RlLCBTZGtQcm92aWRlciB9IGZyb20gJy4uL2FwaSc7XG5pbXBvcnQgeyB6aXBEaXJlY3RvcnkgfSBmcm9tICcuLi91dGlsL2FyY2hpdmUnO1xuXG5jb25zdCBjYW1lbENhc2UgPSByZXF1aXJlKCdjYW1lbGNhc2UnKTtcbmNvbnN0IGRlY2FtZWxpemUgPSByZXF1aXJlKCdkZWNhbWVsaXplJyk7XG5cbi8qKiBUaGUgbGlzdCBvZiBsYW5ndWFnZXMgc3VwcG9ydGVkIGJ5IHRoZSBidWlsdC1pbiBub2N0aWx1Y2VudCBiaW5hcnkuICovXG5leHBvcnQgY29uc3QgTUlHUkFURV9TVVBQT1JURURfTEFOR1VBR0VTOiByZWFkb25seSBzdHJpbmdbXSA9IGNka19mcm9tX2Nmbi5zdXBwb3J0ZWRfbGFuZ3VhZ2VzKCk7XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgQ0RLIGFwcCBmcm9tIGEgeWFtbCBvciBqc29uIHRlbXBsYXRlLlxuICpcbiAqIEBwYXJhbSBzdGFja05hbWUgVGhlIG5hbWUgdG8gYXNzaWduIHRvIHRoZSBzdGFjayBpbiB0aGUgZ2VuZXJhdGVkIGFwcFxuICogQHBhcmFtIHN0YWNrIFRoZSB5YW1sIG9yIGpzb24gdGVtcGxhdGUgZm9yIHRoZSBzdGFja1xuICogQHBhcmFtIGxhbmd1YWdlIFRoZSBsYW5ndWFnZSB0byBnZW5lcmF0ZSB0aGUgQ0RLIGFwcCBpblxuICogQHBhcmFtIG91dHB1dFBhdGggVGhlIHBhdGggYXQgd2hpY2ggdG8gZ2VuZXJhdGUgdGhlIENESyBhcHBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ2RrQXBwKHN0YWNrTmFtZTogc3RyaW5nLCBzdGFjazogc3RyaW5nLCBsYW5ndWFnZTogc3RyaW5nLCBvdXRwdXRQYXRoPzogc3RyaW5nLCBjb21wcmVzcz86IGJvb2xlYW4pIHtcbiAgY29uc3QgcmVzb2x2ZWRPdXRwdXRQYXRoID0gcGF0aC5qb2luKG91dHB1dFBhdGggPz8gcHJvY2Vzcy5jd2QoKSwgc3RhY2tOYW1lKTtcbiAgY29uc3QgZm9ybWF0dGVkU3RhY2tOYW1lID0gZGVjYW1lbGl6ZShzdGFja05hbWUpO1xuXG4gIHRyeSB7XG4gICAgZnMucm1TeW5jKHJlc29sdmVkT3V0cHV0UGF0aCwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgIGZzLm1rZGlyU3luYyhyZXNvbHZlZE91dHB1dFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGNvbnN0IGdlbmVyYXRlT25seSA9IGNvbXByZXNzO1xuICAgIGF3YWl0IGNsaUluaXQoe1xuICAgICAgdHlwZTogJ2FwcCcsXG4gICAgICBsYW5ndWFnZSxcbiAgICAgIGNhblVzZU5ldHdvcms6IHRydWUsXG4gICAgICBnZW5lcmF0ZU9ubHksXG4gICAgICB3b3JrRGlyOiByZXNvbHZlZE91dHB1dFBhdGgsXG4gICAgICBzdGFja05hbWUsXG4gICAgfSk7XG5cbiAgICBsZXQgc3RhY2tGaWxlTmFtZTogc3RyaW5nO1xuICAgIHN3aXRjaCAobGFuZ3VhZ2UpIHtcbiAgICAgIGNhc2UgJ3R5cGVzY3JpcHQnOlxuICAgICAgICBzdGFja0ZpbGVOYW1lID0gYCR7cmVzb2x2ZWRPdXRwdXRQYXRofS9saWIvJHtmb3JtYXR0ZWRTdGFja05hbWV9LXN0YWNrLnRzYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdqYXZhJzpcbiAgICAgICAgc3RhY2tGaWxlTmFtZSA9IGAke3Jlc29sdmVkT3V0cHV0UGF0aH0vc3JjL21haW4vamF2YS9jb20vbXlvcmcvJHtjYW1lbENhc2UoZm9ybWF0dGVkU3RhY2tOYW1lLCB7IHBhc2NhbENhc2U6IHRydWUgfSl9U3RhY2suamF2YWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncHl0aG9uJzpcbiAgICAgICAgc3RhY2tGaWxlTmFtZSA9IGAke3Jlc29sdmVkT3V0cHV0UGF0aH0vJHtmb3JtYXR0ZWRTdGFja05hbWUucmVwbGFjZSgvLS9nLCAnXycpfS8ke2Zvcm1hdHRlZFN0YWNrTmFtZS5yZXBsYWNlKC8tL2csICdfJyl9X3N0YWNrLnB5YDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjc2hhcnAnOlxuICAgICAgICBzdGFja0ZpbGVOYW1lID0gYCR7cmVzb2x2ZWRPdXRwdXRQYXRofS9zcmMvJHtjYW1lbENhc2UoZm9ybWF0dGVkU3RhY2tOYW1lLCB7IHBhc2NhbENhc2U6IHRydWUgfSl9LyR7Y2FtZWxDYXNlKGZvcm1hdHRlZFN0YWNrTmFtZSwgeyBwYXNjYWxDYXNlOiB0cnVlIH0pfVN0YWNrLmNzYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdnbyc6XG4gICAgICAgIHN0YWNrRmlsZU5hbWUgPSBgJHtyZXNvbHZlZE91dHB1dFBhdGh9LyR7Zm9ybWF0dGVkU3RhY2tOYW1lfS5nb2A7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2xhbmd1YWdlfSBpcyBub3Qgc3VwcG9ydGVkIGJ5IENESyBNaWdyYXRlLiBQbGVhc2UgY2hvb3NlIGZyb206ICR7TUlHUkFURV9TVVBQT1JURURfTEFOR1VBR0VTLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIGZzLndyaXRlRmlsZVN5bmMoc3RhY2tGaWxlTmFtZSwgc3RhY2spO1xuICAgIGlmIChjb21wcmVzcykge1xuICAgICAgYXdhaXQgemlwRGlyZWN0b3J5KHJlc29sdmVkT3V0cHV0UGF0aCwgYCR7cmVzb2x2ZWRPdXRwdXRQYXRofS56aXBgKTtcbiAgICAgIGZzLnJtU3luYyhyZXNvbHZlZE91dHB1dFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgZnMucm1TeW5jKHJlc29sdmVkT3V0cHV0UGF0aCwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgQ0RLIHN0YWNrIGZpbGUuXG4gKiBAcGFyYW0gdGVtcGxhdGUgVGhlIHRlbXBsYXRlIHRvIHRyYW5zbGF0ZSBpbnRvIGEgQ0RLIHN0YWNrXG4gKiBAcGFyYW0gc3RhY2tOYW1lIFRoZSBuYW1lIHRvIGFzc2lnbiB0byB0aGUgc3RhY2tcbiAqIEBwYXJhbSBsYW5ndWFnZSBUaGUgbGFuZ3VhZ2UgdG8gZ2VuZXJhdGUgdGhlIHN0YWNrIGluXG4gKiBAcmV0dXJucyBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIENESyBzdGFjayBmaWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVN0YWNrKHRlbXBsYXRlOiBzdHJpbmcsIHN0YWNrTmFtZTogc3RyaW5nLCBsYW5ndWFnZTogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgZm9ybWF0dGVkU3RhY2tOYW1lID0gYCR7Y2FtZWxDYXNlKGRlY2FtZWxpemUoc3RhY2tOYW1lKSwgeyBwYXNjYWxDYXNlOiB0cnVlIH0pfVN0YWNrYDtcbiAgICByZXR1cm4gY2RrX2Zyb21fY2ZuLnRyYW5zbXV0ZSh0ZW1wbGF0ZSwgbGFuZ3VhZ2UsIGZvcm1hdHRlZFN0YWNrTmFtZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0YWNrIGdlbmVyYXRpb24gZmFpbGVkIGR1ZSB0byBlcnJvciAnJHsoZSBhcyBFcnJvcikubWVzc2FnZX0nYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZWFkcyBhbmQgcmV0dXJucyBhIHN0YWNrIHRlbXBsYXRlIGZyb20gYSBsb2NhbCBwYXRoLlxuICpcbiAqIEBwYXJhbSBpbnB1dFBhdGggVGhlIGxvY2F0aW9uIG9mIHRoZSB0ZW1wbGF0ZVxuICogQHJldHVybnMgQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRlbXBsYXRlIGlmIHByZXNlbnQsIG90aGVyd2lzZSB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRGcm9tUGF0aChpbnB1dFBhdGg/OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiBpbnB1dFBhdGggPyBmcy5yZWFkRmlsZVN5bmMoaW5wdXRQYXRoLCAndXRmOCcpIDogdW5kZWZpbmVkO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAnJHtpbnB1dFBhdGh9JyBpcyBub3QgYSB2YWxpZCBwYXRoLmApO1xuICB9XG5cbn1cblxuLyoqXG4gKiBSZWFkcyBhbmQgcmV0dXJucyBhIHN0YWNrIHRlbXBsYXRlIGZyb20gYSBkZXBsb3llZCBDbG91ZEZvcm1hdGlvbiBzdGFjay5cbiAqXG4gKiBAcGFyYW0gc3RhY2tOYW1lIFRoZSBuYW1lIG9mIHRoZSBzdGFja1xuICogQHBhcmFtIHNka1Byb3ZpZGVyIFRoZSBzZGsgcHJvdmlkZXIgZm9yIG1ha2luZyBDbG91ZEZvcm1hdGlvbiBjYWxsc1xuICogQHBhcmFtIGVudmlyb25tZW50IFRoZSBhY2NvdW50IGFuZCByZWdpb24gd2hlcmUgdGhlIHN0YWNrIGlzIGRlcGxveWVkXG4gKiBAcmV0dXJucyBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGVtcGxhdGUgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHVuZGVmaW5lZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZEZyb21TdGFjayhzdGFja05hbWU6IHN0cmluZywgc2RrUHJvdmlkZXI6IFNka1Byb3ZpZGVyLCBlbnZpcm9ubWVudDogRW52aXJvbm1lbnQpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBjbG91ZEZvcm1hdGlvbiA9IChhd2FpdCBzZGtQcm92aWRlci5mb3JFbnZpcm9ubWVudChlbnZpcm9ubWVudCwgTW9kZS5Gb3JSZWFkaW5nKSkuc2RrLmNsb3VkRm9ybWF0aW9uKCk7XG5cbiAgcmV0dXJuIChhd2FpdCBjbG91ZEZvcm1hdGlvbi5nZXRUZW1wbGF0ZSh7XG4gICAgU3RhY2tOYW1lOiBzdGFja05hbWUsXG4gIH0pLnByb21pc2UoKSkuVGVtcGxhdGVCb2R5O1xufVxuXG4vKipcbiAqIFNldHMgdGhlIGFjY291bnQgYW5kIHJlZ2lvbiBmb3IgbWFraW5nIENsb3VkRm9ybWF0aW9uIGNhbGxzLlxuICogQHBhcmFtIGFjY291bnQgVGhlIGFjY291bnQgdG8gdXNlXG4gKiBAcGFyYW0gcmVnaW9uIFRoZSByZWdpb24gdG8gdXNlXG4gKiBAcmV0dXJucyBUaGUgZW52aXJvbm1lbnQgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRFbnZpcm9ubWVudChhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcpOiBFbnZpcm9ubWVudCB7XG4gIHJldHVybiB7IGFjY291bnQ6IGFjY291bnQgPz8gVU5LTk9XTl9BQ0NPVU5ULCByZWdpb246IHJlZ2lvbiA/PyBVTktOT1dOX1JFR0lPTiwgbmFtZTogJ2Nkay1taWdyYXRlLWVudicgfTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgdGhhdCBleGFjdGx5IG9uZSBzb3VyY2Ugb3B0aW9uIGhhcyBiZWVuIHByb3ZpZGVkLlxuICogQHBhcmFtIGZyb21QYXRoIFRoZSBjb250ZW50IG9mIHRoZSBmbGFnIGAtLWZyb20tcGF0aGBcbiAqIEBwYXJhbSBmcm9tU3RhY2sgdGhlIGNvbnRlbnQgb2YgdGhlIGZsYWcgYC0tZnJvbS1zdGFja2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlU291cmNlT3B0aW9ucyhmcm9tUGF0aD86IHN0cmluZywgZnJvbVN0YWNrPzogYm9vbGVhbikge1xuICBpZiAoZnJvbVBhdGggJiYgZnJvbVN0YWNrKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBvZiBgLS1mcm9tLXBhdGhgIG9yIGAtLWZyb20tc3RhY2tgIG1heSBiZSBwcm92aWRlZC4nKTtcbiAgfVxuXG4gIGlmICghZnJvbVBhdGggJiYgIWZyb21TdGFjaykge1xuICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIGAtLWZyb20tcGF0aGAgb3IgYC0tZnJvbS1zdGFja2AgbXVzdCBiZSB1c2VkIHRvIHByb3ZpZGUgdGhlIHNvdXJjZSBvZiB0aGUgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUuJyk7XG4gIH1cbn1cbiJdfQ==