UNPKG

@cdktf/hcl2cdk

Version:
668 lines 114 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.generateConfigType = exports.buildImports = exports.providerConstructImports = exports.wrapCodeInConstructor = exports.addImportForCodeContainer = exports.gen = exports.moduleImports = exports.providerImports = exports.constructsImport = exports.cdktfImport = exports.provider = exports.imports = exports.modules = exports.local = exports.variable = exports.variableTypeToAst = exports.output = exports.resource = exports.backendToExpression = exports.valueToTs = exports.attributeNameToCdktfName = void 0; // Copyright (c) HashiCorp, Inc // SPDX-License-Identifier: MPL-2.0 const generator_1 = __importDefault(require("@babel/generator")); const template_1 = __importDefault(require("@babel/template")); const t = __importStar(require("@babel/types")); const prettier_1 = __importDefault(require("prettier")); const utils_1 = require("./utils"); const expressions_1 = require("./expressions"); const references_1 = require("./references"); const provider_generator_1 = require("@cdktf/provider-generator"); const terraformSchema_1 = require("./terraformSchema"); const commons_1 = require("@cdktf/commons"); const hcl2json_1 = require("@cdktf/hcl2json"); const dynamic_blocks_1 = require("./dynamic-blocks"); const variables_1 = require("./variables"); const util_1 = require("cdktf/lib/util"); const partialCode_1 = require("./partialCode"); function getReference(graph, id) { utils_1.logger.debug(`Finding reference for ${id}`); const neighbors = graph.outNeighbors(id); if (neighbors.length > 0) { utils_1.logger.debug(`Found neighbors ${neighbors} for ${id}`); const edge = graph.directedEdge(id, neighbors[0]); if (edge) { utils_1.logger.debug(`Found first edge ${edge} for ${id}`); utils_1.logger.debug(`Returning reference ${graph.getEdgeAttribute(edge, "ref")}`); return graph.getEdgeAttribute(edge, "ref"); } else { utils_1.logger.debug(`Found no edge for ${id}`); return undefined; } } else { return undefined; } } function attributeNameToCdktfName(name) { return (0, provider_generator_1.escapeAttributeName)((0, utils_1.camelCase)(name)); } exports.attributeNameToCdktfName = attributeNameToCdktfName; const valueToTs = async (scope, item, path, isModule = false) => { switch (typeof item) { case "string": if ((await (0, references_1.findUsedReferences)(scope.nodeIds, item)).some((ref) => path.startsWith(ref.referencee.id))) { return t.stringLiteral(item); } return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${item}"`, () => (0, terraformSchema_1.getDesiredType)(scope, path)); case "boolean": return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `${item}`, () => (0, terraformSchema_1.getDesiredType)(scope, path)); case "number": return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `${item}`, () => (0, terraformSchema_1.getDesiredType)(scope, path)); case "object": { if (item === undefined || item === null) { return t.nullLiteral(); } // For iterators and dynamic blocks we put the correct TS expression in the config ahead of time if (t.isNode(item) && t.isExpression(item)) { return item; } const attributeType = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, path); function shouldRemoveArrayBasedOnType(attributeType) { if (!attributeType) { return false; // The default assumption is we need the array } // maps and object don't need to be wrapped in an array if (Array.isArray(attributeType) && (attributeType[0] === "map" || attributeType[0] === "object")) { return true; } // If it's a block type with max_items = 1 we don't need to wrap it in an array if (typeof attributeType === "object" && "max_items" in attributeType && attributeType.max_items === 1) { return true; } return false; } const unwrappedItem = Array.isArray(item) && (shouldRemoveArrayBasedOnType(attributeType) || path.endsWith("lifecycle") || path.endsWith("connection")) ? item[0] : item; if (Array.isArray(unwrappedItem)) { return t.arrayExpression(await Promise.all(unwrappedItem.map((i) => (0, exports.valueToTs)(scope, i, `${path}.[]`)))); } return t.objectExpression((await Promise.all(Object.entries(unwrappedItem).map(async ([key, value]) => { if (value === undefined) { return undefined; } if (key === "dynamic") { const { for_each, ...others } = value; const dynamicRef = Object.keys(others)[0]; return t.objectProperty(t.identifier(scope.withinOverrideExpression ? dynamicRef : (0, provider_generator_1.escapeAttributeName)((0, utils_1.camelCase)(dynamicRef))), t.arrayExpression()); } const itemPath = `${path}.${key}`; const itemAttributeType = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, itemPath); const typeMetadata = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, itemPath); const isSingleItemBlock = typeMetadata && typeof typeMetadata === "object" && Object.prototype.hasOwnProperty.call(typeMetadata, "max_items") ? typeMetadata.max_items === 1 : false; const shouldBeArray = typeof value === "object" && !Array.isArray(value) && !(t.isNode(value) && t.isExpression(value)) && !isSingleItemBlock && // Map type attributes must not be wrapped in arrays !(0, terraformSchema_1.isMapAttribute)(itemAttributeType) && key !== "tags" && key !== "forEach" && key !== "lifecycle"; const keepKeyName = !isModule && key !== "depends_on" && !path.includes("lifecycle") && (key === "for_each" || !typeMetadata || (0, terraformSchema_1.isMapAttribute)(attributeType)) && !(path.startsWith("var.") && path.includes("validation")); return t.objectProperty(t.stringLiteral(keepKeyName ? key : attributeNameToCdktfName(key)), shouldBeArray ? t.arrayExpression([await (0, exports.valueToTs)(scope, value, itemPath)]) : await (0, exports.valueToTs)(scope, value, itemPath)); }))).filter((expr) => expr !== undefined)); } } throw new Error("Unsupported type " + item); }; exports.valueToTs = valueToTs; async function backendToExpression(scope, tf) { return (await Promise.all(Object.entries(tf || {}).map(async ([type, [config]]) => { const backendIdentifier = (0, utils_1.pascalCase)(`${type}Backend`); scope.importables.push({ constructName: backendIdentifier, provider: "cdktf", }); return t.expressionStatement(t.newExpression(t.identifier(backendIdentifier), [ t.thisExpression(), t.objectExpression((await Promise.all(Object.entries(config).map(async ([property, value]) => t.objectProperty(t.identifier((0, utils_1.camelCase)(property)), await (0, exports.valueToTs)(scope, value, "path-for-backends-can-be-ignored"))))).reduce((carry, item) => [...carry, item], [])), ])); }))).reduce((carry, item) => [...carry, item], []); } exports.backendToExpression = backendToExpression; function addOverrideExpression(variable, path, value, explanatoryComment) { const ast = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(variable), t.identifier("addOverride")), [t.stringLiteral(path), value])); if (explanatoryComment) { t.addComment(ast, "leading", explanatoryComment); } return ast; } function addOverrideLogicalIdExpression(variable, logicalId) { const ast = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(variable), t.identifier("overrideLogicalId")), [t.stringLiteral(logicalId)])); t.addComment(ast, "leading", "This allows the Terraform resource name to match the original name. You can remove the call if you don't need them to match."); return ast; } function getRemoteStateType(item) { const backendRecord = item.find((val) => val.backend); if (backendRecord) { const backend = backendRecord.backend; switch (backend) { case "remote": return ""; case "etcdv3": return "_etcd_v3"; default: return `_${backend}`; } } else { return ""; } } function resourceType(provider, name, item) { switch (provider) { case "data.terraform": return `cdktf.data_terraform_${name.join("_")}${getRemoteStateType(item)}`; case "null": return `NullProvider.${name.join("_")}`; default: return `${provider}.${name.join("_")}`; } } function mapConfigPerResourceType(resource, item) { // Backends have a slightly different API if (resource.startsWith("cdktf.data_terraform_")) { return item.config; } return item; } const loopComment = `In most cases loops should be handled in the programming language context and not inside of the Terraform context. If you are looping over something external, e.g. a variable or a file input you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source you need to keep this like it is.`; async function resource(scope, type, key, id, item, graph) { const [provider, ...name] = type.split("_"); const resource = resourceType(provider, name, item); if (!provider) { throw new Error(`Could not parse resource type '${type}'`); } let expressions = []; const varName = (0, variables_1.variableName)(scope, resource, key); const { for_each, count, provisioner, ...config } = item[0]; const mappedConfig = mapConfigPerResourceType(resource, config); let forEachIteratorName; if (for_each) { forEachIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_for_each_iterator`); const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${for_each}"`, () => ["list", "dynamic"]); scope.importables.push({ provider: "cdktf", constructName: "TerraformIterator", }); const iterator = t.variableDeclaration("const", [ t.variableDeclarator(t.identifier(forEachIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformIterator"), t.identifier("fromList")), [referenceAst])), ]); t.addComment(iterator, "leading", loopComment); expressions.push(iterator); mappedConfig.forEach = t.identifier(forEachIteratorName); } let countIteratorName; if (count) { countIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_count`); const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${count}"`, () => "number"); scope.importables.push({ provider: "cdktf", constructName: "TerraformCount", }); const iterator = t.variableDeclaration("const", [ t.variableDeclarator(t.identifier(countIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformCount"), t.identifier("of")), [referenceAst])), ]); t.addComment(iterator, "leading", loopComment); mappedConfig.count = t.identifier(countIteratorName); expressions.push(iterator); } const dynBlocks = (0, dynamic_blocks_1.extractDynamicBlocks)(mappedConfig); const nestedDynamicBlocks = dynBlocks.filter((block) => (0, dynamic_blocks_1.isNestedDynamicBlock)(dynBlocks, block)); const dynamicBlocksUsingOverrides = dynBlocks.filter((block) => // nested blocks need overrides nestedDynamicBlocks.includes(block) || // blocks that contain nested blocks need them as well nestedDynamicBlocks.some((nestedBlock) => nestedBlock.path.startsWith(block.path))); // all others can be handled by the CDKTF runtime const dynamicBlocksUsingRuntime = dynBlocks.filter((block) => !dynamicBlocksUsingOverrides.includes(block)); for (const [i, block] of dynamicBlocksUsingRuntime.entries()) { const dynamicBlockIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_dynamic_iterator_${i}`); const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${block.for_each}"`, () => ["list", "dynamic"]); scope.importables.push({ provider: "cdktf", constructName: "TerraformIterator", }); const iterator = t.variableDeclaration("const", [ t.variableDeclarator(t.identifier(dynamicBlockIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformIterator"), t.identifier("fromList")), [referenceAst])), ]); t.addComment(iterator, "leading", loopComment); expressions.push(iterator); const dynamicCallExpression = t.callExpression(t.memberExpression(t.identifier(dynamicBlockIteratorName), t.identifier("dynamic")), [ await (0, exports.valueToTs)({ ...scope, scopedVariables: { [block.scopedVar]: dynamicBlockIteratorName, }, }, (0, partialCode_1.fillWithConfigAccessors)(scope, Array.isArray(block.content) ? block.content[0] : block.content, block.path.replace(block.scopedVar, "")), block.path.replace(block.scopedVar, ""), false), ]); const parts = block.path .replace(`dynamic.${block.scopedVar}`, "") .split(".") .filter((p) => p.length > 0); const parent = parts.reduce((acc, part) => { if (Array.isArray(acc) && !Number.isNaN(parseInt(part, 10))) { return acc[parseInt(part, 10)]; } else { return acc[part]; } }, mappedConfig); parent[block.scopedVar] = dynamicCallExpression; delete parent.dynamic; } const overrideReference = dynamicBlocksUsingOverrides.length ? { start: 0, end: 0, referencee: { id: `${type}.${key}`, full: `${type}.${key}`, }, } : undefined; if (provisioner) { mappedConfig.provisioners = await Promise.all(Object.entries(provisioner).flatMap(([type, p]) => p.map((pp) => (0, exports.valueToTs)(scope, { type, ...pp }, "path-for-provisioners-can-be-ignored")))); } const importGraphId = `import.${resource.replace(".", "_")}.${key}`; const importDefinition = graph.hasNode(importGraphId) ? graph.getNodeAttribute(importGraphId, "value") : undefined; expressions = expressions.concat(await asExpression({ ...scope, forEachIteratorName, countIteratorName }, resource, key, mappedConfig, false, false, getReference(graph, id) || overrideReference, importDefinition)); // Check for dynamic blocks expressions = expressions.concat(await Promise.all(dynamicBlocksUsingOverrides.map(async ({ path, for_each, content }) => { // We need to let the expression conversion know all available // dynamic block names, so we don't replace them. The "dynamic-block" // scoped variable indicates to the expression conversion to use the // key name instead of an iterator const scopedVariablesInPath = Object.fromEntries(path .substring(1) // The path starts with a dot that results in an empty split .split(".") .filter((p) => !["dynamic", "content"].includes(p) && isNaN(parseInt(p))) .map((p) => [p, "dynamic-block"])); return addOverrideExpression(varName, path.substring(1), // The path starts with a dot that we don't want await (0, exports.valueToTs)({ ...scope, withinOverrideExpression: true, scopedVariables: scopedVariablesInPath, }, { for_each, content, }, "path-for-dynamic-blocks-can-be-ignored"), loopComment); }))); return expressions; } exports.resource = resource; async function asExpression(scope, type, name, config, isModuleImport, isProvider, reference, imported) { const { providers, ...otherOptions } = config; const constructId = (0, utils_1.uniqueId)(scope.constructs, name); const overrideId = !isProvider && constructId !== name; const completeObject = (0, partialCode_1.fillWithConfigAccessors)(scope, otherOptions, type); const expression = t.newExpression((0, variables_1.constructAst)(scope, type, isModuleImport), [ t.thisExpression(), t.stringLiteral(constructId), await (0, exports.valueToTs)(scope, { ...completeObject, providers: providers && Object.keys(providers).length ? Object.entries(providers).map(([key, value]) => ({ moduleAlias: key, provider: value, })) : undefined, }, `${type}`, isModuleImport), ]); const statements = []; const varName = reference ? (0, variables_1.referenceToVariableName)(scope, reference) : (0, variables_1.variableName)(scope, type, name); if (reference || overrideId || imported) { statements.push(t.variableDeclaration("const", [ t.variableDeclarator(t.identifier(varName), expression), ])); } else { statements.push(t.expressionStatement(expression)); } if (overrideId) { statements.push(addOverrideLogicalIdExpression(varName, name)); } if (imported) { // Adds myVar.importFrom("my-arn") const importExpression = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(varName), t.identifier("importFrom")), [t.stringLiteral(imported.id)])); if (imported.provider) { t.addComment(importExpression, "leading", `This import was configured with a provider. CDKTF does support this, but the cdktf convert command does not yet. Please add the provider reference manually. See https://developer.hashicorp.com/terraform/cdktf/concepts/resources#importing-resources for more information.`); } statements.push(importExpression); } return statements; } async function output(scope, key, _id, item, _graph) { const [{ value, description, sensitive }] = item; return asExpression(scope, "cdktf.TerraformOutput", key, { value, description, sensitive, }, false, false, undefined, undefined); } exports.output = output; async function variableTypeToAst(scope, type) { const addVariableTypeToImports = () => scope.importables.push({ constructName: "VariableType", provider: "cdktf", }); function parsedTypeToAst(type) { if (hcl2json_1.TFExpressionSyntaxTree.isScopeTraversalExpression(type)) { addVariableTypeToImports(); switch (type.meta.value) { case "string": return t.identifier("VariableType.STRING"); case "number": return t.identifier("VariableType.NUMBER"); case "bool": return t.identifier("VariableType.BOOL"); case "any": default: return t.identifier("VariableType.ANY"); } } if (hcl2json_1.TFExpressionSyntaxTree.isFunctionCallExpression(type)) { addVariableTypeToImports(); switch (type.meta.name) { case "list": case "set": case "map": case "tuple": case "object": return t.callExpression(t.identifier(`VariableType.${type.meta.name}`), type.children.map((child) => parsedTypeToAst(child))); } } if (hcl2json_1.TFExpressionSyntaxTree.isObjectExpression(type)) { return t.objectExpression(Object.entries(type.meta.items).map(([key, value]) => t.objectProperty(t.stringLiteral(key), // This does not deal with complex types nested within objects // If such a type is found it will result in an Any type // e.g. { foo: list(string) } will result in { foo: any } parsedTypeToAst({ type: "scopeTraversal", meta: { value }, })))); } addVariableTypeToImports(); return t.identifier("VariableType.ANY"); } return parsedTypeToAst(await (0, expressions_1.expressionAst)(type)); } exports.variableTypeToAst = variableTypeToAst; async function variable(scope, key, id, item, graph) { const [{ type, ...props }] = item; if (!getReference(graph, id)) { return []; } return asExpression(scope, id, key, { ...props, type: type ? await variableTypeToAst(scope, type) : undefined }, false, false, getReference(graph, id), undefined); } exports.variable = variable; async function local(scope, key, id, item, graph) { utils_1.logger.debug(`Initializing local resource ${key} with id ${id}`); if (!getReference(graph, id)) { utils_1.logger.debug(`No reference found for ${key}`); return []; } return [ t.variableDeclaration("const", [ t.variableDeclarator(t.identifier((0, variables_1.variableName)(scope, "local", key)), await (0, exports.valueToTs)(scope, item, "path-for-local-blocks-can-be-ignored")), ]), ]; } exports.local = local; async function modules(scope, key, id, item, graph) { const [{ source, version, ...props }] = item; const moduleConstraint = new provider_generator_1.TerraformModuleConstraint(source); return asExpression(scope, moduleConstraint.className, key, props, true, false, getReference(graph, id), undefined); } exports.modules = modules; async function imports(scope, _id, item, graph) { // Move from ${aws_instance.example} to aws_instance.example const target = item.to.startsWith("${") && item.to.endsWith("}") ? item.to.substring(2, item.to.length - 1) : item.to; // Check if the import goes into a module if (target.startsWith("module.")) { return [ t.addComment(t.emptyStatement(), "leading", `CDKTF does not support imports into modules yet, please remove the import block importing ${item.id} into ${target} from your configuration`), ]; } // We now know that the import goes into a resource, e.g. aws_instance.example const [resourceTypeIdentifier, resourceName] = target.split("."); if (resourceName.includes("[")) { return [ t.addComment(t.emptyStatement(), "leading", `CDKTF does not support imports into resources with count or for_each yet, please remove the import block importing ${item.id} into ${target} from your configuration`), ]; } // Check if we have a existing resource config with the given name if (graph.hasNode(target)) { // We will handle this case in the resource function // so we can skip over it return []; } const [provider, ...resourceTypeNameParts] = resourceTypeIdentifier.split("_"); const constructId = (0, utils_1.uniqueId)(scope.constructs, (0, utils_1.camelCase)(resourceName)); const constructClass = (0, variables_1.constructAst)(scope, `${provider}.${resourceTypeNameParts.join("_")}`, false); return [ t.expressionStatement(t.callExpression(t.memberExpression(constructClass, t.identifier("generateConfigForImport")), [ t.thisExpression(), t.stringLiteral(constructId), t.stringLiteral(item.id), ])), ]; } exports.imports = imports; async function provider(scope, key, id, item, graph) { const { version, ...props } = item; const importKey = key === "null" ? "NullProvider" : key; return asExpression(scope, `${importKey}.${(0, utils_1.pascalCase)(key)}Provider`, key, props, false, true, getReference(graph, id), undefined); } exports.provider = provider; exports.cdktfImport = (0, template_1.default)(`import * as cdktf from "cdktf"`)(); exports.constructsImport = (0, template_1.default)(`import * as constructs from "constructs"`)(); const providerImports = (providers) => providers.map((providerName) => { const parts = providerName.split("/"); const name = parts.length > 1 ? parts[1] : parts[0]; const importName = name === "null" ? "NullProvider" : name; return (0, template_1.default)(`import * as ${importName} from "./.gen/providers/${name.replace("./", "")}"`)(); }); exports.providerImports = providerImports; const moduleImports = (modules) => { const uniqueModules = new Set(); Object.values(modules || {}).map(([module]) => uniqueModules.add(module.source)); const imports = []; uniqueModules.forEach((m) => { const moduleConstraint = new provider_generator_1.TerraformModuleConstraint(m); imports.push(template_1.default.ast(`import * as ${moduleConstraint.className} from "./.gen/modules/${moduleConstraint.fileName}"`)); }); return imports; }; exports.moduleImports = moduleImports; async function gen(statements) { utils_1.logger.debug(`Generating code for ${JSON.stringify(statements, null, 2)}`); const code = prettier_1.default.format((0, generator_1.default)(t.program(statements)).code, { parser: "babel", }); utils_1.logger.debug(`Generated code:\n${code}`); return code; } exports.gen = gen; function addImportForCodeContainer(scope, codeContainer) { switch (codeContainer) { case "constructs.Construct": scope.importables.push({ provider: "constructs", constructName: "Construct", }); break; case "cdktf.TerraformStack": scope.importables.push({ provider: "cdktf", constructName: "TerraformStack", }); break; default: throw commons_1.Errors.Internal("Unsupported code container: " + codeContainer); } } exports.addImportForCodeContainer = addImportForCodeContainer; function wrapCodeInConstructor(codeContainer, code, className, configTypeName) { let baseContainerClass; switch (codeContainer) { case "constructs.Construct": baseContainerClass = t.identifier("Construct"); break; case "cdktf.TerraformStack": baseContainerClass = t.identifier("TerraformStack"); break; default: throw commons_1.Errors.Internal("Unsupported code container: " + codeContainer); } if (configTypeName) { return template_1.default.statement(` class %%className%% extends %%base%% { constructor(scope: Construct, name: string, config: ${configTypeName}) { super(scope, name); %%code%% } } `, { syntacticPlaceholders: true, plugins: ["typescript"] })({ code, base: baseContainerClass, className: t.identifier(className), }); } return template_1.default.statement(` class %%className%% extends %%base%% { constructor(scope: Construct, name: string) { super(scope, name); %%code%% } } `, { syntacticPlaceholders: true, plugins: ["typescript"] })({ code, base: baseContainerClass, className: t.identifier(className), }); } exports.wrapCodeInConstructor = wrapCodeInConstructor; const providerConstructImports = (importable) => { let provider = importable[0].provider; let namespace = importable[0].namespace; const names = importable.map((i) => i.constructName); if (provider === "cdktf" || provider === "constructs") { return (0, template_1.default)(`import { ${names.join(", ")} } from "${provider}"`)(); } if (namespace) { namespace = (0, util_1.snakeCase)(namespace).replace(/_/g, "-"); } // Special cases to undo provider names that we override if (provider === "NullProvider") { provider = "null"; } return (0, template_1.default)(`import { ${names.join(", ")} } from "./.gen/providers/${provider}/${namespace}"`)(); }; exports.providerConstructImports = providerConstructImports; function buildImports(importables) { const groupedImportables = importables.reduce((acc, importable) => { const ns = importable.namespace || ""; // Doing some hacky ordering of the imports to make them look a bit nicer const prefix = importable.provider === "constructs" ? "1" : importable.provider === "cdktf" ? "2" : "3"; const groupName = `${prefix}.${importable.provider}.${ns}`; const fullName = `${importable.provider}.${ns}.${importable.constructName}`; if (acc[groupName]) { const existsAlready = acc[groupName].some((importable) => `${importable.provider}.${ns}.${importable.constructName}` === fullName); if (existsAlready) { return acc; } acc[groupName].push(importable); acc[groupName].sort(); } else { acc[groupName] = [importable]; } return acc; }, {}); let commentAdded = false; const constructImports = Object.keys(groupedImportables) .sort() .map((groupName) => { const importStatement = (0, exports.providerConstructImports)(groupedImportables[groupName]); if (groupName.startsWith("3.") && !commentAdded) { commentAdded = true; t.addComment(importStatement, "leading", `\n* Provider bindings are generated by running \`cdktf get\`. * See https://cdk.tf/provider-generation for more details.\n`); } return importStatement; }); return constructImports; } exports.buildImports = buildImports; function generateConfigType(name, config) { return t.tsInterfaceDeclaration(t.identifier(name), undefined, undefined, t.tsInterfaceBody(Object.entries(config).map(([key, _value]) => t.tsPropertySignature(t.identifier(key), t.tSTypeAnnotation(t.tsAnyKeyword()))))); } exports.generateConfigType = generateConfigType; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImdlbmVyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLGlFQUF3QztBQUN4QywrREFBdUM7QUFDdkMsZ0RBQWtDO0FBRWxDLHdEQUFnQztBQVNoQyxtQ0FBa0U7QUFVbEUsK0NBQThFO0FBRTlFLDZDQUFrRDtBQUNsRCxrRUFHbUM7QUFDbkMsdURBSTJCO0FBQzNCLDRDQUEwRTtBQUMxRSw4Q0FBZ0U7QUFDaEUscURBQThFO0FBQzlFLDJDQUlxQjtBQUNyQix5Q0FBMkM7QUFDM0MsK0NBQXdEO0FBRXhELFNBQVMsWUFBWSxDQUFDLEtBQW9CLEVBQUUsRUFBVTtJQUNwRCxjQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFekMsSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3pCLGNBQU0sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLFNBQVMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWxELElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxjQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixJQUFJLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNuRCxjQUFNLENBQUMsS0FBSyxDQUNWLHVCQUF1QixLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQzdELENBQUM7WUFDRixPQUFPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJ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