@cdktf/hcl2cdk
Version:
Transform HCL into CDK
239 lines • 28.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findExpressionType = exports.coerceType = exports.typeForCallExpression = void 0;
// Copyright (c) HashiCorp, Inc
// SPDX-License-Identifier: MPL-2.0
const template_1 = __importDefault(require("@babel/template"));
const t = __importStar(require("@babel/types"));
const commons_1 = require("@cdktf/commons");
const deep_equal_1 = __importDefault(require("deep-equal"));
const functions_1 = require("./function-bindings/functions");
const terraformSchema_1 = require("./terraformSchema");
const codemaker_1 = require("codemaker");
function changeValueAccessor(ast, newAccessor) {
const propertyIdentifier = {
...ast.property,
name: newAccessor,
};
return {
...ast,
property: propertyIdentifier,
};
}
function typeForCallExpression(ast) {
// Find all cdktf.Fn.* calls
if (t.isMemberExpression(ast.callee) &&
t.isMemberExpression(ast.callee.object) &&
t.isIdentifier(ast.callee.object.object) &&
ast.callee.object.object.name === "cdktf" &&
t.isIdentifier(ast.callee.object.property) &&
ast.callee.object.property.name === "Fn" &&
t.isIdentifier(ast.callee.property)) {
const meta = functions_1.tsFunctionsMap[ast.callee.property.name];
if (meta) {
return meta.returnType;
}
else {
return "dynamic";
}
}
// cdktf.conditional, cdktf.propertyAccess, cdktf.Op.* are all dynamic
// By default we assume dynamic
return "dynamic";
}
exports.typeForCallExpression = typeForCallExpression;
const coerceType = (scope, ast, from, to) => {
if (to === undefined) {
return ast;
}
if ((0, deep_equal_1.default)(to, from)) {
return ast;
}
const isTerraformVariableOrLocal = ast.type === "MemberExpression" &&
ast.property.type === "Identifier" &&
ast.property.name === "value" &&
ast.object.type === "Identifier" &&
Object.values(scope.variables).some((knownVars) => knownVars.variableName === ast.object.name &&
["var", "local"].includes(knownVars.resource));
const addTokenToImports = () => scope.importables.push({
constructName: "Token",
provider: "cdktf",
});
if (Array.isArray(to)) {
if (to[0] === "list" || to[0] === "set") {
switch (to[1]) {
case "string":
if (isTerraformVariableOrLocal) {
return changeValueAccessor(ast, "listValue");
}
addTokenToImports();
return template_1.default.expression(`Token.asList(%%ast%%)`)({
ast: ast,
});
case "number":
addTokenToImports();
return template_1.default.expression(`Token.asNumberList(%%ast%%)`)({
ast: ast,
});
case "bool":
addTokenToImports();
return template_1.default.expression(`Token.asAny(%%ast%%)`)({
ast: ast,
});
default:
addTokenToImports();
return template_1.default.expression(`Token.asAny(%%ast%%)`)({
ast: ast,
});
}
}
if (to[0] === "map") {
switch (to[1]) {
case "string":
addTokenToImports();
return template_1.default.expression(`Token.asStringMap(%%ast%%)`)({
ast: ast,
});
case "number":
addTokenToImports();
return template_1.default.expression(`Token.asNumberMap(%%ast%%)`)({
ast: ast,
});
case "bool":
addTokenToImports();
return template_1.default.expression(`Token.asBooleanMap(%%ast%%)`)({
ast: ast,
});
default:
addTokenToImports();
return template_1.default.expression(`Token.asAnyMap(%%ast%%)`)({
ast: ast,
});
}
}
}
switch (to) {
case "number":
if (isTerraformVariableOrLocal) {
return changeValueAccessor(ast, "numberValue");
}
addTokenToImports();
return template_1.default.expression(`Token.asNumber(%%ast%%)`)({
ast: ast,
});
case "string":
if (isTerraformVariableOrLocal) {
return changeValueAccessor(ast, "stringValue");
}
addTokenToImports();
return template_1.default.expression(`Token.asString(%%ast%%)`)({
ast: ast,
});
case "bool":
if (isTerraformVariableOrLocal) {
return changeValueAccessor(ast, "booleanValue");
}
addTokenToImports();
return template_1.default.expression(`Token.asBoolean(%%ast%%)`)({
ast: ast,
});
}
commons_1.logger.debug(`Could not coerce from ${from} to ${to} for ${ast}`);
return ast;
};
exports.coerceType = coerceType;
function findExpressionType(scope, ast) {
const isReferenceWithoutTemplateString = ast.type === "MemberExpression" && ast.object.type === "Identifier";
// If we have a property to cdktf.propertyAccess call it's dynamic
if (ast.type === "CallExpression") {
return typeForCallExpression(ast);
}
if (ast.type === "StringLiteral") {
return "string";
}
if (ast.type === "NumericLiteral") {
return "number";
}
if (ast.type === "BooleanLiteral") {
return "bool";
}
// If we only have one reference this is a
if (isReferenceWithoutTemplateString) {
const destructuredAst = destructureAst(ast);
if (!destructuredAst) {
commons_1.logger.debug(`Could not destructure ast: ${JSON.stringify(ast, null, 2)}`);
return "dynamic";
}
const [astVariableName, ...attributes] = destructuredAst;
const variable = Object.values(scope.variables).find((x) => x.variableName === astVariableName);
if (!variable) {
commons_1.logger.debug(`Could not find variable ${astVariableName} given scope: ${JSON.stringify(scope.variables, null, 2)}`);
// We don't know, this should not happen, but if it does we assume the worst case and make it dynamic
return "dynamic";
}
if (variable.resource === "var") {
return "dynamic";
}
const { resource: resourceType } = variable;
const [provider, ...resourceNameFragments] = resourceType.split("_");
const tfResourcePath = `${provider}.${resourceNameFragments.join("_")}.${attributes.map((x) => (0, codemaker_1.toSnakeCase)(x)).join(".")}`;
const type = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, tfResourcePath);
// If this is an attribute type we can return it
if (typeof type === "string" || Array.isArray(type)) {
return type;
}
// Either nothing is found or it's a block type
return "dynamic";
}
return "string";
}
exports.findExpressionType = findExpressionType;
/*
* Transforms a babel AST into a list of string accessors
* e.g. foo.bar.baz -> ["foo", "bar", "baz"]
*/
function destructureAst(ast) {
switch (ast.type) {
case "Identifier":
return [ast.name];
case "MemberExpression": {
const object = destructureAst(ast.object);
const property = destructureAst(ast.property);
if (object && property) {
return [...object, ...property];
}
else {
return undefined;
}
}
default:
return undefined;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29lcmNlVHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvZXJjZVR5cGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLCtEQUF1QztBQUN2QyxnREFBa0M7QUFDbEMsNENBQXVEO0FBRXZELDREQUFtQztBQUNuQyw2REFBK0Q7QUFDL0QsdURBQWtEO0FBQ2xELHlDQUF3QztBQUV4QyxTQUFTLG1CQUFtQixDQUMxQixHQUF1QixFQUN2QixXQUFtQjtJQUVuQixNQUFNLGtCQUFrQixHQUFpQjtRQUN2QyxHQUFJLEdBQUcsQ0FBQyxRQUF5QjtRQUNqQyxJQUFJLEVBQUUsV0FBVztLQUNsQixDQUFDO0lBQ0YsT0FBTztRQUNMLEdBQUcsR0FBRztRQUNOLFFBQVEsRUFBRSxrQkFBa0I7S0FDN0IsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQixxQkFBcUIsQ0FBQyxHQUFxQjtJQUN6RCw0QkFBNEI7SUFDNUIsSUFDRSxDQUFDLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztRQUNoQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDdkMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDeEMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxPQUFPO1FBQ3pDLENBQUMsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBQzFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssSUFBSTtRQUN4QyxDQUFDLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxD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QUFDO1lBQ2xDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1FBQ0gsQ0FBQztRQUNEO1lBQ0UsT0FBTyxTQUFTLENBQUM7SUFDckIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIEhhc2hpQ29ycCwgSW5jXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTVBMLTIuMFxuaW1wb3J0IHRlbXBsYXRlIGZyb20gXCJAYmFiZWwvdGVtcGxhdGVcIjtcbmltcG9ydCAqIGFzIHQgZnJvbSBcIkBiYWJlbC90eXBlc1wiO1xuaW1wb3J0IHsgbG9nZ2VyLCBBdHRyaWJ1dGVUeXBlIH0gZnJvbSBcIkBjZGt0Zi9jb21tb25zXCI7XG5pbXBvcnQgeyBQcm9ncmFtU2NvcGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IGRlZXBFcXVhbCBmcm9tIFwiZGVlcC1lcXVhbFwiO1xuaW1wb3J0IHsgdHNGdW5jdGlvbnNNYXAgfSBmcm9tIFwiLi9mdW5jdGlvbi1iaW5kaW5ncy9mdW5jdGlvbnNcIjtcbmltcG9ydCB7IGdldFR5cGVBdFBhdGggfSBmcm9tIFwiLi90ZXJyYWZvcm1TY2hlbWFcIjtcbmltcG9ydCB7IHRvU25ha2VDYXNlIH0gZnJvbSBcImNvZGVtYWtlclwiO1xuXG5mdW5jdGlvbiBjaGFuZ2VWYWx1ZUFjY2Vzc29yKFxuICBhc3Q6IHQuTWVtYmVyRXhwcmVzc2lvbixcbiAgbmV3QWNjZXNzb3I6IHN0cmluZyxcbik6IHQuTWVtYmVyRXhwcmVzc2lvbiB7XG4gIGNvbnN0IHByb3BlcnR5SWRlbnRpZmllcjogdC5JZGVudGlmaWVyID0ge1xuICAgIC4uLihhc3QucHJvcGVydHkgYXMgdC5JZGVudGlmaWVyKSxcbiAgICBuYW1lOiBuZXdBY2Nlc3NvcixcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICAuLi5hc3QsXG4gICAgcHJvcGVydHk6IHByb3BlcnR5SWRlbnRpZmllcixcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHR5cGVGb3JDYWxsRXhwcmVzc2lvbihhc3Q6IHQuQ2FsbEV4cHJlc3Npb24pOiBBdHRyaWJ1dGVUeXBlIHtcbiAgLy8gRmluZCBhbGwgY2RrdGYuRm4uKiBjYWxsc1xuICBpZiAoXG4gICAgdC5pc01lbWJlckV4cHJlc3Npb24oYXN0LmNhbGxlZSkgJiZcbiAgICB0LmlzTWVtYmVyRXhwcmVzc2lvbihhc3QuY2FsbGVlLm9iamVjdCkgJiZcbiAgICB0LmlzSWRlbnRpZmllcihhc3QuY2FsbGVlLm9iamVjdC5vYmplY3QpICYmXG4gICAgYXN0LmNhbGxlZS5vYmplY3Qub2JqZWN0Lm5hbWUgPT09IFwiY2RrdGZcIiAmJlxuICAgIHQuaXNJZGVudGlmaWVyKGFzdC5jYWxsZWUub2JqZWN0LnByb3BlcnR5KSAmJlxuICAgIGFzdC5jYWxsZWUub2JqZWN0LnByb3BlcnR5Lm5hbWUgPT09IFwiRm5cIiAmJlxuICAgIHQuaXNJZGVudGlmaWVyKGFzdC5jYWxsZWUucHJvcGVydHkpXG4gICkge1xuICAgIGNvbnN0IG1ldGEgPSB0c0Z1bmN0aW9uc01hcFthc3QuY2FsbGVlLnByb3BlcnR5Lm5hbWVdO1xuICAgIGlmIChtZXRhKSB7XG4gICAgICByZXR1cm4gbWV0YS5yZXR1cm5UeXBlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJkeW5hbWljXCI7XG4gICAgfVxuICB9XG5cbiAgLy8gY2RrdGYuY29uZGl0aW9uYWwsIGNka3RmLnByb3BlcnR5QWNjZXNzLCBjZGt0Zi5PcC4qIGFyZSBhbGwgZHluYW1pY1xuICAvLyBCeSBkZWZhdWx0IHdlIGFzc3VtZSBkeW5hbWljXG4gIHJldHVybiBcImR5bmFtaWNcIjtcbn1cblxuZXhwb3J0IGNvbnN0IGNvZXJjZVR5cGUgPSAoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIGFzdDogdC5FeHByZXNzaW9uLFxuICBmcm9tOiBBdHRyaWJ1dGVUeXBlLFxuICB0bzogQXR0cmlidXRlVHlwZSB8IHVuZGVmaW5lZCxcbik6IHQuRXhwcmVzc2lvbiA9PiB7XG4gIGlmICh0byA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGFzdDtcbiAgfVxuXG4gIGlmIChkZWVwRXF1YWwodG8sIGZyb20pKSB7XG4gICAgcmV0dXJuIGFzdDtcbiAgfVxuXG4gIGNvbnN0IGlzVGVycmFmb3JtVmFyaWFibGVPckxvY2FsID1cbiAgICBhc3QudHlwZSA9PT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgJiZcbiAgICBhc3QucHJvcGVydHkudHlwZSA9PT0gXCJJZGVudGlmaWVyXCIgJiZcbiAgICBhc3QucHJvcGVydHkubmFtZSA9PT0gXCJ2YWx1ZVwiICYmXG4gICAgYXN0Lm9iamVjdC50eXBlID09PSBcIklkZW50aWZpZXJcIiAmJlxuICAgIE9iamVjdC52YWx1ZXMoc2NvcGUudmFyaWFibGVzKS5zb21lKFxuICAgICAgKGtub3duVmFycykgPT5cbiAgICAgICAga25vd25WYXJzLnZhcmlhYmxlTmFtZSA9PT0gKGFzdC5vYmplY3QgYXMgdC5JZGVudGlmaWVyKS5uYW1lICYmXG4gICAgICAgIFtcInZhclwiLCBcImxvY2FsXCJdLmluY2x1ZGVzKGtub3duVmFycy5yZXNvdXJjZSksXG4gICAgKTtcblxuICBjb25zdCBhZGRUb2tlblRvSW1wb3J0cyA9ICgpID0+XG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBjb25zdHJ1Y3ROYW1lOiBcIlRva2VuXCIsXG4gICAgICBwcm92aWRlcjogXCJjZGt0ZlwiLFxuICAgIH0pO1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHRvKSkge1xuICAgIGlmICh0b1swXSA9PT0gXCJsaXN0XCIgfHwgdG9bMF0gPT09IFwic2V0XCIpIHtcbiAgICAgIHN3aXRjaCAodG9bMV0pIHtcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgIGlmIChpc1RlcnJhZm9ybVZhcmlhYmxlT3JMb2NhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGNoYW5nZVZhbHVlQWNjZXNzb3IoYXN0IGFzIHQuTWVtYmVyRXhwcmVzc2lvbiwgXCJsaXN0VmFsdWVcIik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYWRkVG9rZW5Ub0ltcG9ydHMoKTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGUuZXhwcmVzc2lvbihgVG9rZW4uYXNMaXN0KCUlYXN0JSUpYCkoe1xuICAgICAgICAgICAgYXN0OiBhc3QsXG4gICAgICAgICAgfSkgYXMgdC5FeHByZXNzaW9uO1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgYWRkVG9rZW5Ub0ltcG9ydHMoKTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGUuZXhwcmVzc2lvbihgVG9rZW4uYXNOdW1iZXJMaXN0KCUlYXN0JSUpYCkoe1xuICAgICAgICAgICAgYXN0OiBhc3QsXG4gICAgICAgICAgfSkgYXMgdC5FeHByZXNzaW9uO1xuICAgICAgICBjYXNlIFwiYm9vbFwiOlxuICAgICAgICAgIGFkZFRva2VuVG9JbXBvcnRzKCk7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlLmV4cHJlc3Npb24oYFRva2VuLmFzQW55KCUlYXN0JSUpYCkoe1xuICAgICAgICAgICAgYXN0OiBhc3QsXG4gICAgICAgICAgfSkgYXMgdC5FeHByZXNzaW9uO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGFkZFRva2VuVG9JbXBvcnRzKCk7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlLmV4cHJlc3Npb24oYFRva2VuLmFzQW55KCUlYXN0JSUpYCkoe1xuICAgICAgICAgICAgYXN0OiBhc3QsXG4gICAgICAgICAgfSkgYXMgdC5FeHByZXNzaW9uO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0b1swXSA9PT0gXCJtYXBcIikge1xuICAgICAgc3dpdGNoICh0b1sxXSkge1xuICAgICAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICAgICAgYWRkVG9rZW5Ub0ltcG9ydHMoKTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGUuZXhwcmVzc2lvbihgVG9rZW4uYXNTdHJpbmdNYXAoJSVhc3QlJSlgKSh7XG4gICAgICAgICAgICBhc3Q6IGFzdCxcbiAgICAgICAgICB9KSBhcyB0LkV4cHJlc3Npb247XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICBhZGRUb2tlblRvSW1wb3J0cygpO1xuICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5leHByZXNzaW9uKGBUb2tlbi5hc051bWJlck1hcCglJWFzdCUlKWApKHtcbiAgICAgICAgICAgIGFzdDogYXN0LFxuICAgICAgICAgIH0pIGFzIHQuRXhwcmVzc2lvbjtcbiAgICAgICAgY2FzZSBcImJvb2xcIjpcbiAgICAgICAgICBhZGRUb2tlblRvSW1wb3J0cygpO1xuICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5leHByZXNzaW9uKGBUb2tlbi5hc0Jvb2xlYW5NYXAoJSVhc3QlJSlgKSh7XG4gICAgICAgICAgICBhc3Q6IGFzdCxcbiAgICAgICAgICB9KSBhcyB0LkV4cHJlc3Npb247XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgYWRkVG9rZW5Ub0ltcG9ydHMoKTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGUuZXhwcmVzc2lvbihgVG9rZW4uYXNBbnlNYXAoJSVhc3QlJSlgKSh7XG4gICAgICAgICAgICBhc3Q6IGFzdCxcbiAgICAgICAgICB9KSBhcyB0LkV4cHJlc3Npb247XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3dpdGNoICh0bykge1xuICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGlmIChpc1RlcnJhZm9ybVZhcmlhYmxlT3JMb2NhbCkge1xuICAgICAgICByZXR1cm4gY2hhbmdlVmFsdWVBY2Nlc3Nvcihhc3QgYXMgdC5NZW1iZXJFeHByZXNzaW9uLCBcIm51bWJlclZhbHVlXCIpO1xuICAgICAgfVxuICAgICAgYWRkVG9rZW5Ub0ltcG9ydHMoKTtcbiAgICAgIHJldHVybiB0ZW1wbGF0ZS5leHByZXNzaW9uKGBUb2tlbi5hc051bWJlciglJWFzdCUlKWApKHtcbiAgICAgICAgYXN0OiBhc3QsXG4gICAgICB9KSBhcyB0LkV4cHJlc3Npb247XG4gICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgaWYgKGlzVGVycmFmb3JtVmFyaWFibGVPckxvY2FsKSB7XG4gICAgICAgIHJldHVybiBjaGFuZ2VWYWx1ZUFjY2Vzc29yKGFzdCBhcyB0Lk1lbWJlckV4cHJlc3Npb24sIFwic3RyaW5nVmFsdWVcIik7XG4gICAgICB9XG4gICAgICBhZGRUb2tlblRvSW1wb3J0cygpO1xuICAgICAgcmV0dXJuIHRlbXBsYXRlLmV4cHJlc3Npb24oYFRva2VuLmFzU3RyaW5nKCUlYXN0JSUpYCkoe1xuICAgICAgICBhc3Q6IGFzdCxcbiAgICAgIH0pIGFzIHQuRXhwcmVzc2lvbjtcbiAgICBjYXNlIFwiYm9vbFwiOlxuICAgICAgaWYgKGlzVGVycmFmb3JtVmFyaWFibGVPckxvY2FsKSB7XG4gICAgICAgIHJldHVybiBjaGFuZ2VWYWx1ZUFjY2Vzc29yKGFzdCBhcyB0Lk1lbWJlckV4cHJlc3Npb24sIFwiYm9vbGVhblZhbHVlXCIpO1xuICAgICAgfVxuICAgICAgYWRkVG9rZW5Ub0ltcG9ydHMoKTtcbiAgICAgIHJldHVybiB0ZW1wbGF0ZS5leHByZXNzaW9uKGBUb2tlbi5hc0Jvb2xlYW4oJSVhc3QlJSlgKSh7XG4gICAgICAgIGFzdDogYXN0LFxuICAgICAgfSkgYXMgdC5FeHByZXNzaW9uO1xuICB9XG5cbiAgbG9nZ2VyLmRlYnVnKGBDb3VsZCBub3QgY29lcmNlIGZyb20gJHtmcm9tfSB0byAke3RvfSBmb3IgJHthc3R9YCk7XG4gIHJldHVybiBhc3Q7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZEV4cHJlc3Npb25UeXBlKFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICBhc3Q6IHQuRXhwcmVzc2lvbixcbik6IEF0dHJpYnV0ZVR5cGUge1xuICBjb25zdCBpc1JlZmVyZW5jZVdpdGhvdXRUZW1wbGF0ZVN0cmluZyA9XG4gICAgYXN0LnR5cGUgPT09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmIGFzdC5vYmplY3QudHlwZSA9PT0gXCJJZGVudGlmaWVyXCI7XG5cbiAgLy8gSWYgd2UgaGF2ZSBhIHByb3BlcnR5IHRvIGNka3RmLnByb3BlcnR5QWNjZXNzIGNhbGwgaXQncyBkeW5hbWljXG4gIGlmIChhc3QudHlwZSA9PT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIHR5cGVGb3JDYWxsRXhwcmVzc2lvbihhc3QpO1xuICB9XG5cbiAgaWYgKGFzdC50eXBlID09PSBcIlN0cmluZ0xpdGVyYWxcIikge1xuICAgIHJldHVybiBcInN0cmluZ1wiO1xuICB9XG4gIGlmIChhc3QudHlwZSA9PT0gXCJOdW1lcmljTGl0ZXJhbFwiKSB7XG4gICAgcmV0dXJuIFwibnVtYmVyXCI7XG4gIH1cbiAgaWYgKGFzdC50eXBlID09PSBcIkJvb2xlYW5MaXRlcmFsXCIpIHtcbiAgICByZXR1cm4gXCJib29sXCI7XG4gIH1cblxuICAvLyBJZiB3ZSBvbmx5IGhhdmUgb25lIHJlZmVyZW5jZSB0aGlzIGlzIGFcbiAgaWYgKGlzUmVmZXJlbmNlV2l0aG91dFRlbXBsYXRlU3RyaW5nKSB7XG4gICAgY29uc3QgZGVzdHJ1Y3R1cmVkQXN0ID0gZGVzdHJ1Y3R1cmVBc3QoYXN0KTtcbiAgICBpZiAoIWRlc3RydWN0dXJlZEFzdCkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgQ291bGQgbm90IGRlc3RydWN0dXJlIGFzdDogJHtKU09OLnN0cmluZ2lmeShhc3QsIG51bGwsIDIpfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIFwiZHluYW1pY1wiO1xuICAgIH1cblxuICAgIGNvbnN0IFthc3RWYXJpYWJsZU5hbWUsIC4uLmF0dHJpYnV0ZXNdID0gZGVzdHJ1Y3R1cmVkQXN0O1xuICAgIGNvbnN0IHZhcmlhYmxlID0gT2JqZWN0LnZhbHVlcyhzY29wZS52YXJpYWJsZXMpLmZpbmQoXG4gICAgICAoeCkgPT4geC52YXJpYWJsZU5hbWUgPT09IGFzdFZhcmlhYmxlTmFtZSxcbiAgICApO1xuXG4gICAgaWYgKCF2YXJpYWJsZSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgdmFyaWFibGUgJHthc3RWYXJpYWJsZU5hbWV9IGdpdmVuIHNjb3BlOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIHNjb3BlLnZhcmlhYmxlcyxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIDIsXG4gICAgICAgICl9YCxcbiAgICAgICk7XG4gICAgICAvLyBXZSBkb24ndCBrbm93LCB0aGlzIHNob3VsZCBub3QgaGFwcGVuLCBidXQgaWYgaXQgZG9lcyB3ZSBhc3N1bWUgdGhlIHdvcnN0IGNhc2UgYW5kIG1ha2UgaXQgZHluYW1pY1xuICAgICAgcmV0dXJuIFwiZHluYW1pY1wiO1xuICAgIH1cblxuICAgIGlmICh2YXJpYWJsZS5yZXNvdXJjZSA9PT0gXCJ2YXJcIikge1xuICAgICAgcmV0dXJuIFwiZHluYW1pY1wiO1xuICAgIH1cblxuICAgIGNvbnN0IHsgcmVzb3VyY2U6IHJlc291cmNlVHlwZSB9ID0gdmFyaWFibGU7XG4gICAgY29uc3QgW3Byb3ZpZGVyLCAuLi5yZXNvdXJjZU5hbWVGcmFnbWVudHNdID0gcmVzb3VyY2VUeXBlLnNwbGl0KFwiX1wiKTtcbiAgICBjb25zdCB0ZlJlc291cmNlUGF0aCA9IGAke3Byb3ZpZGVyfS4ke3Jlc291cmNlTmFtZUZyYWdtZW50cy5qb2luKFxuICAgICAgXCJfXCIsXG4gICAgKX0uJHthdHRyaWJ1dGVzLm1hcCgoeCkgPT4gdG9TbmFrZUNhc2UoeCkpLmpvaW4oXCIuXCIpfWA7XG4gICAgY29uc3QgdHlwZSA9IGdldFR5cGVBdFBhdGgoc2NvcGUucHJvdmlkZXJTY2hlbWEsIHRmUmVzb3VyY2VQYXRoKTtcblxuICAgIC8vIElmIHRoaXMgaXMgYW4gYXR0cmlidXRlIHR5cGUgd2UgY2FuIHJldHVybiBpdFxuICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gXCJzdHJpbmdcIiB8fCBBcnJheS5pc0FycmF5KHR5cGUpKSB7XG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9XG5cbiAgICAvLyBFaXRoZXIgbm90aGluZyBpcyBmb3VuZCBvciBpdCdzIGEgYmxvY2sgdHlwZVxuICAgIHJldHVybiBcImR5bmFtaWNcIjtcbiAgfVxuXG4gIHJldHVybiBcInN0cmluZ1wiO1xufVxuXG4vKlxuICogVHJhbnNmb3JtcyBhIGJhYmVsIEFTVCBpbnRvIGEgbGlzdCBvZiBzdHJpbmcgYWNjZXNzb3JzXG4gKiBlLmcuIGZvby5iYXIuYmF6IC0+IFtcImZvb1wiLCBcImJhclwiLCBcImJhelwiXVxuICovXG5mdW5jdGlvbiBkZXN0cnVjdHVyZUFzdChhc3Q6IHQuRXhwcmVzc2lvbik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgc3dpdGNoIChhc3QudHlwZSkge1xuICAgIGNhc2UgXCJJZGVudGlmaWVyXCI6XG4gICAgICByZXR1cm4gW2FzdC5uYW1lXTtcbiAgICBjYXNlIFwiTWVtYmVyRXhwcmVzc2lvblwiOiB7XG4gICAgICBjb25zdCBvYmplY3QgPSBkZXN0cnVjdHVyZUFzdChhc3Qub2JqZWN0KTtcbiAgICAgIGNvbnN0IHByb3BlcnR5ID0gZGVzdHJ1Y3R1cmVBc3QoYXN0LnByb3BlcnR5IGFzIHQuRXhwcmVzc2lvbik7XG4gICAgICBpZiAob2JqZWN0ICYmIHByb3BlcnR5KSB7XG4gICAgICAgIHJldHVybiBbLi4ub2JqZWN0LCAuLi5wcm9wZXJ0eV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19