UNPKG

@cdktf/hcl2cdk

Version:
634 lines 99 kB
"use strict"; 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.dynamicVariableToAst = exports.extractIteratorVariablesFromExpression = exports.convertTerraformExpressionToTs = exports.expressionAst = void 0; // Copyright (c) HashiCorp, Inc // SPDX-License-Identifier: MPL-2.0 const t = __importStar(require("@babel/types")); const template_1 = __importDefault(require("@babel/template")); const utils_1 = require("./utils"); const hcl2json_1 = require("@cdktf/hcl2json"); const hcl2json_2 = require("@cdktf/hcl2json"); const functions_1 = require("./function-bindings/functions"); const coerceType_1 = require("./coerceType"); const terraformSchema_1 = require("./terraformSchema"); const references_1 = require("./references"); const variables_1 = require("./variables"); const syntax_tree_1 = require("@cdktf/hcl2json/lib/syntax-tree"); const tfBinaryOperatorsToCdktf = { logicalOr: "or", logicalAnd: "and", greaterThan: "gt", greaterThanOrEqual: "gte", lessThan: "lt", lessThanOrEqual: "lte", equal: "eq", notEqual: "neq", add: "add", subtract: "sub", multiply: "mul", divide: "div", modulo: "mod", }; const tfUnaryOperatorsToCdktf = { logicalNot: "not", negate: "negate", }; function traversalPartsToString(traversals, asSuffix = false) { let seed = ""; if (asSuffix && hcl2json_2.TFExpressionSyntaxTree.isNameTraversalPart(traversals[0])) { seed = "."; } return traversals.reduce((acc, part) => { if (part.type === "nameTraversal") { if (acc === seed) { return `${acc}${part.segment}`; } return `${acc}.${part.segment}`; } return `${acc}[${part.segment}]`; }, seed); } function canUseFqn(expression) { if (!hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(expression)) { return false; } const rootSegment = expression.meta.traversal[0].segment; return !["var", "local"].includes(rootSegment); } function traversalToVariableName(scope, node) { if (!hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node)) { utils_1.logger.error(`Unexpected expression type ${node.type} with value ${node.meta.value} passed to convert to a variable. ${utils_1.leaveCommentText}`); return ""; } const segments = node.meta.traversal; if (segments.length === 1) { return node.meta.fullAccessor; } const rootSegment = segments[0].segment; const resource = rootSegment === "data" ? `${segments[0].segment}.${segments[1].segment}` : rootSegment; const name = rootSegment === "data" ? segments[2].segment : segments[1].segment; return (0, variables_1.variableName)(scope, resource, name); } function expressionForSerialStringConcatenation(scope, nodes) { const reducedNodes = nodes.reduce((acc, node) => { const prev = acc[acc.length - 1]; if (!prev) return [node]; if (t.isStringLiteral(prev) && t.isStringLiteral(node)) { acc.pop(); acc.push(t.stringLiteral(prev.value + node.value)); return acc; } acc.push(node); return acc; }, []); return reducedNodes.reduce((acc, node) => { if (!acc) { return node; } // wrap access to dynamic blocks in Token.asString() as they return a Lazy // for .key and .value which can't be concatenated in languages like Python // because JSII currently has no support for the toString() method in // languages other than TypeScript: https://github.com/aws/jsii/issues/380 // example: dynamic_iterator0.key / dynamic_iterator0.value if (t.isMemberExpression(node) && t.isIdentifier(node.object) && Object.values(scope.scopedVariables || {}).includes(node.object.name) && t.isIdentifier(node.property) && ["key", "value"].includes(node.property.name)) { node = (0, coerceType_1.coerceType)(scope, node, "dynamic", "string"); } return t.binaryExpression("+", acc, node); }); } function getTfResourcePathFromNode(node) { const segments = node.meta.traversal; let resource = segments[0].segment; let result = []; let attributes = []; if (segments[0].segment === "data") { result.push(segments[0].segment); resource = segments[1].segment; attributes = segments.slice(3); // we want to skip the variable name } else { attributes = segments.slice(2); // we want to skip the variable name } const [provider, ...resourceNameFragments] = resource.split("_"); // Hack: This happens in the case of `external` provider // where the data source does not have a provider name prefix if (resourceNameFragments.length === 0) { resourceNameFragments.push(provider); } result.push(provider); result.push(resourceNameFragments.join("_")); result = [ ...result, ...attributes.map((seg) => { if (hcl2json_2.TFExpressionSyntaxTree.isIndexTraversalPart(seg)) { return `[${seg.segment}]`; } return seg.segment; }), ]; return result.join("."); } function convertLiteralValueExpressionToTs(_scope, node) { const literalType = node.meta.type; if (literalType === "number") { return t.numericLiteral(Number(node.meta.value)); } if (literalType === "bool") { return t.booleanLiteral(node.meta.value === "true" ? true : false); } return t.stringLiteral(node.meta.value); } function convertScopeTraversalExpressionToTs(scope, node) { var _a; const hasReference = (0, references_1.containsReference)(node); const segments = node.meta.traversal; if (segments[0].segment === "each" && scope.forEachIteratorName) { return dynamicVariableToAst(scope, node, scope.forEachIteratorName); } if (segments[0].segment === "count" && scope.countIteratorName) { return dynamicVariableToAst(scope, node, scope.countIteratorName, "count"); } if (segments[0].segment === "self") { scope.importables.push({ constructName: "TerraformSelf", provider: "cdktf", }); return t.callExpression(t.memberExpression(t.identifier("TerraformSelf"), t.identifier("getAny")), [t.stringLiteral(traversalPartsToString(segments.slice(1)))]); } // setting.value, setting.value[1].id const dynamicBlock = (_a = scope.scopedVariables) === null || _a === void 0 ? void 0 : _a[segments[0].segment]; if (dynamicBlock) { if (dynamicBlock === "dynamic-block") { return dynamicVariableToAst(scope, node, dynamicBlock, traversalPartsToString(segments)); } return dynamicVariableToAst(scope, node, dynamicBlock, segments[0].segment); } // This may be a variable reference that we don't understand yet, so we wrap it in a template string // for Terraform to handle let varIdentifier = t.stringLiteral(`\${${node.meta.fullAccessor}}`); if (hasReference) { varIdentifier = t.identifier((0, utils_1.camelCase)(traversalToVariableName(scope, node))); } if (["var", "local"].includes(segments[0].segment)) { const variableAccessor = segments[0].segment === "var" ? t.memberExpression(varIdentifier, t.identifier("value")) : varIdentifier; if (segments.length > 2) { scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested")); return t.callExpression(callee, [ variableAccessor, t.arrayExpression(segments.slice(2).map((s) => t.stringLiteral(s.segment))), ]); } return variableAccessor; } if (!hasReference || scope.withinOverrideExpression) { return varIdentifier; } const rootSegment = segments[0].segment; const attributeIndex = rootSegment === "data" ? 3 : 2; const attributeSegments = segments.slice(attributeIndex); const numericAccessorIndex = attributeSegments.findIndex((seg) => hcl2json_2.TFExpressionSyntaxTree.isIndexTraversalPart(seg)); let minAccessorIndex = numericAccessorIndex; let mapAccessorIndex = -1; if (numericAccessorIndex === -1) { // only do this if we have to, if we already have a // numeric accessor, we don't have to do this additional work const resourcePath = getTfResourcePathFromNode(node); let usingSubPathType = false; let parts = resourcePath.split(".").filter((p) => p !== ""); const minParts = attributeIndex; // we need to stop before data.aws.resource_name or aws.resource_name const originalParts = parts.length; let hasMapAccessor = false; while (parts.length >= minParts) { const type = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, parts.join(".")); if (type !== null) { if (Array.isArray(type) && type[0] === "map" && usingSubPathType) { hasMapAccessor = true; break; } } parts.pop(); usingSubPathType = true; } if (hasMapAccessor) { mapAccessorIndex = originalParts - parts.length - 1; minAccessorIndex = mapAccessorIndex; } } const needsPropertyAccess = minAccessorIndex >= 0; const refSegments = needsPropertyAccess ? attributeSegments.slice(0, minAccessorIndex) : attributeSegments; const nonRefSegments = needsPropertyAccess ? attributeSegments.slice(minAccessorIndex) : []; const ref = refSegments.reduce((acc, seg, index) => t.memberExpression(acc, t.identifier(index === 0 && rootSegment === "module" ? (0, utils_1.camelCase)(seg.segment + "Output") : (0, utils_1.camelCase)(seg.segment))), varIdentifier); if (nonRefSegments.length === 0) { return ref; } scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested")); return t.callExpression(callee, [ ref, t.arrayExpression(nonRefSegments.map((s) => t.stringLiteral(s.segment))), ]); } function convertUnaryOpExpressionToTs(scope, node) { const operand = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.valueExpression)); let fnName = node.meta.operator; if (tfUnaryOperatorsToCdktf[fnName]) { fnName = tfUnaryOperatorsToCdktf[fnName]; } else { throw new Error(`Cannot convert unknown operator ${node.meta.operator}`); } scope.importables.push({ constructName: "Op", provider: "cdktf", }); const fn = t.memberExpression(t.identifier("Op"), t.identifier(fnName)); return t.callExpression(fn, [operand]); } function convertBinaryOpExpressionToTs(scope, node) { const left = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.lhsExpression)); const right = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.rhsExpression)); let fnName = node.meta.operator; if (tfBinaryOperatorsToCdktf[fnName]) { fnName = tfBinaryOperatorsToCdktf[fnName]; } else { throw new Error(`Cannot convert unknown operator ${node.meta.operator}`); } scope.importables.push({ constructName: "Op", provider: "cdktf", }); const fn = t.memberExpression(t.identifier("Op"), t.identifier(fnName)); return t.callExpression(fn, [left, right]); } function convertTemplateExpressionToTs(scope, node) { const parts = node.children.map((child) => ({ node: child, expr: convertTFExpressionAstToTs(scope, child), })); const lastPart = parts[parts.length - 1]; if (t.isStringLiteral(lastPart.expr) && lastPart.expr.value === "\n") { // This is a bit of a hack, but the trailing newline we add due to // heredocs looks ugly and unnecessary in the generated code, so we // try to remove it parts.pop(); } if (parts.length === 0) { return t.stringLiteral(node.meta.value); } if (parts.length === 1) { return parts[0].expr; } let isScopedTraversal = false; let expressions = []; for (const { node, expr } of parts) { if (hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node) && !t.isStringLiteral(expr) && !t.isCallExpression(expr)) { expressions.push(t.stringLiteral("${")); isScopedTraversal = true; } else if ( // we should ideally be doing type coercion more // carefully here, because it may not always be needed t.isCallExpression(expr)) { scope.importables.push({ constructName: "Token", provider: "cdktf", }); expressions.push(template_1.default.expression(`Token.asString(%%expr%%)`)({ expr, })); continue; } else { if (isScopedTraversal) { expressions.push(t.stringLiteral("}")); isScopedTraversal = false; } } expressions.push(expr); } if (isScopedTraversal) { expressions.push(t.stringLiteral("}")); } return expressionForSerialStringConcatenation(scope, expressions); } function convertObjectExpressionToTs(scope, node) { return t.objectExpression(Object.entries(node.meta.items) .map(([key, value]) => { const valueChild = (0, syntax_tree_1.getChildWithValue)(node, value); if (!valueChild) { utils_1.logger.error(`Unable to value for object key '${key}': ${value}`); return null; } return t.objectProperty(t.identifier(key), convertTFExpressionAstToTs(scope, valueChild)); }) .filter((s) => s !== null)); } function convertFunctionCallExpressionToTs(scope, node) { const functionName = node.meta.name; const mapping = functions_1.functionsMap[functionName]; if (!mapping) { utils_1.logger.error(`Unknown function ${functionName} encountered. ${utils_1.leaveCommentText}`); const argumentExpressions = node.children.map((child) => convertTFExpressionAstToTs(scope, child)); return t.callExpression(t.identifier(functionName), argumentExpressions); } let transformedNode = mapping.transformer ? mapping.transformer(node) : node; const argumentExpressions = transformedNode.children.map((child) => convertTFExpressionAstToTs(scope, child)); scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier(mapping.name)); if (mapping.parameters.length > 0 && mapping.parameters[mapping.parameters.length - 1].variadic) { const lastParameterType = mapping.parameters[mapping.parameters.length - 1].type; const nonVariadicArguments = argumentExpressions.slice(0, mapping.parameters.length - 1); const fnCallArguments = [ ...nonVariadicArguments.map((argExpr, index) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), mapping.parameters[index].type)), t.arrayExpression(argumentExpressions .slice(mapping.parameters.length - 1) .map((argExpr) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), lastParameterType))), ]; return t.callExpression(callee, fnCallArguments); } return t.callExpression(callee, argumentExpressions.map((argExpr, index) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), mapping.parameters[index].type))); } function convertIndexExpressionToTs(scope, node) { const collectionExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.collectionExpression); const keyExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.keyExpression); const collectionExpression = convertTFExpressionAstToTs(scope, collectionExpressionChild); const keyExpression = convertTFExpressionAstToTs(scope, keyExpressionChild); scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested")); return t.callExpression(callee, [ collectionExpression, t.arrayExpression([keyExpression]), ]); } function convertSplatExpressionToTs(scope, node) { const sourceExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.sourceExpression); let sourceExpression = convertTFExpressionAstToTs(scope, sourceExpressionChild); // We don't convert the relative expression because everything after the splat is going to be // a string let relativeExpression = node.meta.eachExpression.startsWith(node.meta.anonSymbolExpression) ? node.meta.eachExpression.slice(node.meta.anonSymbolExpression.length) : node.meta.eachExpression; const segments = relativeExpression.split(/\.|\[|\]/).filter((s) => s); scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested")); return t.callExpression(callee, [ sourceExpression, t.arrayExpression([ // we don't need to use the anonSymbolExpression here because // it only changes between .* and [*] which we don't care about t.stringLiteral("*"), ...segments.map(t.stringLiteral), ]), ]); } function convertConditionalExpressionToTs(scope, node) { const conditionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.conditionExpression); let condition = convertTFExpressionAstToTs(scope, conditionChild); if (t.isIdentifier(condition) && canUseFqn(conditionChild)) { // We have a resource or data source here, which we would need to // reference using fqn condition = t.memberExpression(condition, t.identifier("fqn")); } const trueExpression = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.trueExpression)); const falseExpression = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.falseExpression)); scope.importables.push({ constructName: "conditional", provider: "cdktf", }); return t.callExpression(t.identifier("conditional"), [ condition, trueExpression, falseExpression, ]); } function convertTupleExpressionToTs(scope, node) { const expressions = node.children.map((child) => convertTFExpressionAstToTs(scope, child)); return t.arrayExpression(expressions); } function convertRelativeTraversalExpressionToTs(scope, node) { const segments = node.meta.traversal; // The left hand side / source of a relative traversal is not a proper // object / resource / data thing that is being referenced const source = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.sourceExpression)); scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested")); return t.callExpression(callee, [ source, t.arrayExpression(segments.map((s) => t.stringLiteral(s.segment))), ]); } function convertForExpressionToTs(scope, node) { const collectionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.collectionExpression); let collectionExpression = convertTFExpressionAstToTs(scope, collectionChild); if (t.isIdentifier(collectionExpression) && canUseFqn(collectionChild)) { // We have a resource or data source here, which we would need to // reference using fqn collectionExpression = t.memberExpression(collectionExpression, t.identifier("fqn")); } const collectionRequiresWrapping = !t.isStringLiteral(collectionExpression); const expressions = []; const conditionBody = node.meta.keyVar ? `${node.meta.keyVar}, ${node.meta.valVar}` : node.meta.valVar; const openBrace = node.meta.openRangeValue; const closeBrace = node.meta.closeRangeValue; const grouped = node.meta.groupedValue ? "..." : ""; const valueExpression = `${node.meta.valueExpression}${grouped}`; const prefix = `\${${openBrace} for ${conditionBody} in `; const keyValue = node.meta.keyExpression ? ` : ${node.meta.keyExpression} => ${valueExpression}` : ` : ${valueExpression}`; const conditional = node.meta.conditionalExpression; const suffix = `${keyValue}${conditional ? ` if ${conditional}` : ""}${closeBrace}}`; expressions.push(t.stringLiteral(prefix)); if (collectionRequiresWrapping) { expressions.push(t.stringLiteral("${")); } expressions.push(collectionExpression); if (collectionRequiresWrapping) { expressions.push(t.stringLiteral("}")); } expressions.push(t.stringLiteral(suffix)); return expressionForSerialStringConcatenation(scope, expressions); } function convertTFExpressionAstToTs(scope, node) { if (hcl2json_2.TFExpressionSyntaxTree.isLiteralValueExpression(node)) { return convertLiteralValueExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node)) { return convertScopeTraversalExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isUnaryOpExpression(node)) { return convertUnaryOpExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isBinaryOpExpression(node)) { return convertBinaryOpExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isTemplateExpression(node) || hcl2json_2.TFExpressionSyntaxTree.isTemplateWrapExpression(node)) { return convertTemplateExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isObjectExpression(node)) { return convertObjectExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isFunctionCallExpression(node)) { return convertFunctionCallExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isIndexExpression(node)) { return convertIndexExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isSplatExpression(node)) { return convertSplatExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isConditionalExpression(node)) { return convertConditionalExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isTupleExpression(node)) { return convertTupleExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isRelativeTraversalExpression(node)) { return convertRelativeTraversalExpressionToTs(scope, node); } if (hcl2json_2.TFExpressionSyntaxTree.isForExpression(node)) { return convertForExpressionToTs(scope, node); } return t.stringLiteral(""); } async function expressionAst(input) { const { wrap, wrapOffset } = (0, hcl2json_2.wrapTerraformExpression)(input); const ast = await (0, hcl2json_1.getExpressionAst)("main.tf", wrap); if (!ast) { throw new Error(`Unable to parse terraform expression: ${input}`); } if (wrapOffset != 0 && hcl2json_2.TFExpressionSyntaxTree.isTemplateWrapExpression(ast)) { return ast.children[0]; } return ast; } exports.expressionAst = expressionAst; async function convertTerraformExpressionToTs(scope, input, targetType) { utils_1.logger.debug(`convertTerraformExpressionToTs(${input})`); const tsExpression = convertTFExpressionAstToTs(scope, await expressionAst(input)); return (0, coerceType_1.coerceType)(scope, tsExpression, (0, coerceType_1.findExpressionType)(scope, tsExpression), targetType()); } exports.convertTerraformExpressionToTs = convertTerraformExpressionToTs; async function extractIteratorVariablesFromExpression(input) { const possibleVariableSpots = await (0, hcl2json_1.getReferencesInExpression)("main.tf", input); return possibleVariableSpots .filter((spot) => spot.value.startsWith("each.")) .map((spot) => ({ start: spot.startPosition, end: spot.endPosition, value: spot.value, })); } exports.extractIteratorVariablesFromExpression = extractIteratorVariablesFromExpression; function dynamicVariableToAst(scope, node, iteratorName, block = "each") { if (iteratorName === "dynamic-block") { return expressionForSerialStringConcatenation(scope, [ t.stringLiteral("${"), t.stringLiteral(block), t.stringLiteral("}"), ]); } if (node.meta.value === `${block}.key`) { return t.memberExpression(t.identifier(iteratorName), t.identifier("key")); } if (node.meta.value === `${block}.value`) { return t.memberExpression(t.identifier(iteratorName), t.identifier("value")); } if (block === "count" && node.meta.value === `${block}.index`) { return t.memberExpression(t.identifier(iteratorName), t.identifier("index")); } const segments = node.meta.traversal; if (segments.length > 2 && segments[0].segment === block && segments[1].segment === "value") { const segmentsAfterEachValue = segments.slice(2); scope.importables.push({ constructName: "Fn", provider: "cdktf", }); const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested")); return t.callExpression(callee, [ t.memberExpression(t.identifier(iteratorName), t.identifier("value")), t.arrayExpression(segmentsAfterEachValue.map((part) => { if (part.type === "nameTraversal") { return t.stringLiteral(part.segment); } else { return t.stringLiteral(`[${part.segment}]`); } })), ]); } throw new Error(`Can not create AST for iterator variable of '${node.meta.value}'`); } exports.dynamicVariableToAst = dynamicVariableToAst; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJleHByZXNzaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtCQUErQjtBQUMvQixtQ0FBbUM7QUFDbkMsZ0RBQWtDO0FBQ2xDLCtEQUF1QztBQUN2QyxtQ0FBOEQ7QUFNOUQsOENBQThFO0FBQzlFLDhDQUd5QjtBQUN6Qiw2REFBNkQ7QUFDN0QsNkNBQThEO0FBRTlELHVEQUFrRDtBQUNsRCw2Q0FBaUQ7QUFDakQsMkNBQTJDO0FBQzNDLGlFQUFvRTtBQUVwRSxNQUFNLHdCQUF3QixHQUFHO0lBQy9CLFNBQVMsRUFBRSxJQUFJO0lBQ2YsVUFBVSxFQUFFLEtBQUs7SUFDakIsV0FBVyxFQUFFLElBQUk7SUFDakIsa0JBQWtCLEVBQUUsS0FBSztJQUN6QixRQUFRLEVBQUUsSUFBSTtJQUNkLGVBQWUsRUFBRSxLQUFLO0lBQ3RCLEtBQUssRUFBRSxJQUFJO0lBQ1gsUUFBUSxFQUFFLEtBQUs7SUFDZixHQUFHLEVBQUUsS0FBSztJQUNWLFFBQVEsRUFBRSxLQUFLO0lBQ2YsUUFBUSxFQUFFLEtBQUs7SUFDZixNQUFNLEVBQUUsS0FBSztJQUNiLE1BQU0sRUFBRSxLQUFLO0NBQ2QsQ0FBQztBQUVGLE1BQU0sdUJBQXVCLEdBQUc7SUFDOUIsVUFBVSxFQUFFLEtBQUs7SUFDakIsTUFBTSxFQUFFLFFBQVE7Q0FDakIsQ0FBQztBQUtGLFNBQVMsc0JBQXNCLENBQzdCLFVBQXdDLEVBQ3hDLFFBQVEsR0FBRyxLQUFLO0lBRWhCLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNkLElBQUksUUFBUSxJQUFJLGlDQUFHLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FB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