@cdktn/hcl2cdk 0.24.0-pre.43 → 0.24.0-pre.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/LICENSE +355 -0
  2. package/README.md +1 -1
  3. package/build/__tests__/expressions.test.js +10 -19
  4. package/build/__tests__/functions.test.js +8 -18
  5. package/build/__tests__/testHelpers.js +3 -2
  6. package/build/coerceType.js +11 -21
  7. package/build/dynamic-blocks.js +3 -3
  8. package/build/expressions.js +13 -22
  9. package/build/function-bindings/functions.generated.js +2 -2
  10. package/build/generation.js +24 -34
  11. package/build/index.js +15 -25
  12. package/build/iteration.js +7 -6
  13. package/build/jsii-rosetta-workarounds.js +6 -5
  14. package/build/partialCode.js +11 -20
  15. package/build/provider.js +4 -3
  16. package/build/references.js +6 -5
  17. package/build/schema.js +8 -18
  18. package/build/terraformSchema.js +4 -4
  19. package/build/utils.js +3 -3
  20. package/build/variables.js +12 -21
  21. package/package.json +20 -17
  22. package/package.sh +1 -1
  23. package/src/__tests__/coerceType.test.ts +207 -0
  24. package/src/__tests__/expressionToTs.test.ts +1167 -0
  25. package/src/__tests__/expressions.test.ts +541 -0
  26. package/src/__tests__/findExpressionType.test.ts +112 -0
  27. package/src/__tests__/functions.test.ts +768 -0
  28. package/src/__tests__/generation.test.ts +72 -0
  29. package/src/__tests__/jsii-rosetta-workarounds.test.ts +145 -0
  30. package/src/__tests__/partialCode.test.ts +432 -0
  31. package/src/__tests__/terraformSchema.test.ts +107 -0
  32. package/src/__tests__/testHelpers.ts +11 -0
  33. package/src/coerceType.ts +261 -0
  34. package/src/dynamic-blocks.ts +61 -0
  35. package/src/expressions.ts +968 -0
  36. package/src/function-bindings/functions.generated.ts +1139 -0
  37. package/src/function-bindings/functions.ts +104 -0
  38. package/src/generation.ts +1189 -0
  39. package/src/index.ts +584 -0
  40. package/src/iteration.ts +156 -0
  41. package/src/jsii-rosetta-workarounds.ts +145 -0
  42. package/src/partialCode.ts +132 -0
  43. package/src/provider.ts +60 -0
  44. package/src/references.ts +193 -0
  45. package/src/schema.ts +74 -0
  46. package/src/terraformSchema.ts +182 -0
  47. package/src/types.ts +58 -0
  48. package/src/utils.ts +19 -0
  49. package/src/variables.ts +214 -0
  50. package/test/__snapshots__/backends.test.ts.snap +70 -0
  51. package/test/__snapshots__/externals.test.ts.snap +37 -0
  52. package/test/__snapshots__/granular-imports.test.ts.snap +180 -0
  53. package/test/__snapshots__/imports.test.ts.snap +159 -0
  54. package/test/__snapshots__/iteration.test.ts.snap +532 -0
  55. package/test/__snapshots__/jsiiLanguage.test.ts.snap +347 -0
  56. package/test/__snapshots__/locals.test.ts.snap +55 -0
  57. package/test/__snapshots__/modules.test.ts.snap +127 -0
  58. package/test/__snapshots__/outputs.test.ts.snap +77 -0
  59. package/test/__snapshots__/partialCode.test.ts.snap +120 -0
  60. package/test/__snapshots__/provider.test.ts.snap +128 -0
  61. package/test/__snapshots__/references.test.ts.snap +376 -0
  62. package/test/__snapshots__/resource-meta-properties.test.ts.snap +342 -0
  63. package/test/__snapshots__/resources.test.ts.snap +613 -0
  64. package/test/__snapshots__/tfExpressions.test.ts.snap +537 -0
  65. package/test/__snapshots__/typeCoercion.test.ts.snap +253 -0
  66. package/test/__snapshots__/variables.test.ts.snap +150 -0
  67. package/test/backends.test.ts +75 -0
  68. package/test/convertProject.test.ts +257 -0
  69. package/test/externals.test.ts +35 -0
  70. package/test/globalSetup.ts +224 -0
  71. package/test/globalTeardown.ts +11 -0
  72. package/test/granular-imports.test.ts +161 -0
  73. package/test/hcl2cdk.test.ts +88 -0
  74. package/test/helpers/convert.ts +543 -0
  75. package/test/helpers/tmp.ts +25 -0
  76. package/test/imports.test.ts +141 -0
  77. package/test/iteration.test.ts +342 -0
  78. package/test/jsiiLanguage.test.ts +73 -0
  79. package/test/locals.test.ts +47 -0
  80. package/test/modules.test.ts +143 -0
  81. package/test/outputs.test.ts +69 -0
  82. package/test/partialCode.test.ts +25 -0
  83. package/test/provider.test.ts +106 -0
  84. package/test/references.test.ts +287 -0
  85. package/test/resource-meta-properties.test.ts +288 -0
  86. package/test/resources.test.ts +551 -0
  87. package/test/tfExpressions.test.ts +300 -0
  88. package/test/typeCoercion.test.ts +154 -0
  89. package/test/variables.test.ts +96 -0
package/src/schema.ts ADDED
@@ -0,0 +1,74 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import * as z from "zod";
4
+
5
+ const tfObject = <T extends z.ZodRawShape>(config: T) =>
6
+ z.array(z.object(config).partial());
7
+
8
+ const outputConfig = tfObject({
9
+ value: z.any(),
10
+ description: z.string().optional(),
11
+ sensitive: z.boolean().optional(),
12
+ depends_on: z.string().optional(),
13
+ });
14
+ export type Output = z.infer<typeof outputConfig>;
15
+
16
+ const validationConfig = z.object({
17
+ error_message: z.string(),
18
+ condition: z.any(),
19
+ });
20
+
21
+ const variableConfig = tfObject({
22
+ type: z.string(),
23
+ default: z.any(),
24
+ description: z.string(),
25
+ sensitive: z.boolean(),
26
+ nullable: z.boolean().optional(),
27
+ validation: z.array(validationConfig).optional(),
28
+ });
29
+ export type Variable = z.infer<typeof variableConfig>;
30
+
31
+ const providerConfig = z.array(z.record(z.any()));
32
+ export type Provider = z.infer<typeof providerConfig>;
33
+
34
+ const moduleConfig = z.array(z.object({ source: z.string() }).nonstrict());
35
+ export type Module = z.infer<typeof moduleConfig>;
36
+
37
+ const resourceConfig = z.array(z.record(z.any()));
38
+ export type Resource = z.infer<typeof resourceConfig>;
39
+ export type Data = Resource;
40
+
41
+ const importConfig = z.object({
42
+ to: z.string(),
43
+ id: z.string(),
44
+ provider: z.any().optional(),
45
+ });
46
+ export type Import = z.infer<typeof importConfig>;
47
+
48
+ const providerSpecification = z.union([
49
+ z.object({ source: z.string(), version: z.string() }).partial(),
50
+ z.string(),
51
+ ]);
52
+
53
+ const terraformConfig = z
54
+ .object({
55
+ required_version: z.string(),
56
+ required_providers: z.array(z.record(providerSpecification)),
57
+ backend: z.record(z.array(z.record(z.any()))),
58
+ })
59
+ .partial();
60
+ export type TerraformConfig = z.infer<typeof terraformConfig>;
61
+
62
+ export const schema = z
63
+ .object({
64
+ data: z.record(z.record(resourceConfig)),
65
+ import: z.array(importConfig),
66
+ locals: z.array(z.record(z.any())),
67
+ module: z.record(moduleConfig),
68
+ output: z.record(outputConfig),
69
+ provider: z.record(providerConfig),
70
+ resource: z.record(z.record(resourceConfig)),
71
+ terraform: z.array(terraformConfig),
72
+ variable: z.record(variableConfig),
73
+ })
74
+ .partial();
@@ -0,0 +1,182 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import {
4
+ ProviderSchema,
5
+ BlockType,
6
+ AttributeType,
7
+ Schema,
8
+ } from "@cdktn/commons";
9
+ import { getFullProviderName } from "./provider";
10
+ import { ProgramScope } from "./types";
11
+
12
+ function getResourceAtPath(schema: ProviderSchema, path: string) {
13
+ const parts = path.split(".");
14
+
15
+ if (parts.length < 2) {
16
+ // Too short to be a valid path
17
+ return null;
18
+ }
19
+
20
+ const isDataSource = parts[0] === "data";
21
+ if (isDataSource) {
22
+ parts.shift();
23
+ }
24
+
25
+ const providerName = parts.shift() as string;
26
+ const resourceName = parts.shift() as string;
27
+
28
+ const fullProviderName = getFullProviderName(schema, providerName);
29
+ // Hack: In the case of 'external', the name of the data source 'external' doesn't have a prefix
30
+ // so we repeat the name as both provider prefix and the data source name
31
+ const fullResourceName =
32
+ providerName === resourceName
33
+ ? providerName
34
+ : `${providerName}_${resourceName}`;
35
+
36
+ if (!fullProviderName) {
37
+ // No provider found with that name
38
+ return null;
39
+ }
40
+
41
+ const provider = schema.provider_schemas?.[fullProviderName];
42
+
43
+ if (!provider) {
44
+ // Could not find provider
45
+ return null;
46
+ }
47
+
48
+ if (resourceName.endsWith("Provider")) {
49
+ // This is a provider
50
+ return { resource: provider.provider, parts };
51
+ }
52
+
53
+ const resources = isDataSource
54
+ ? provider.data_source_schemas
55
+ : provider.resource_schemas;
56
+
57
+ const resource = resources[fullResourceName];
58
+ if (!resource) {
59
+ // Could not find resource
60
+ return null;
61
+ }
62
+
63
+ return { resource, parts };
64
+ }
65
+
66
+ function findType(
67
+ item: Schema | BlockType | AttributeType,
68
+ parts: string[],
69
+ ): Schema | BlockType | AttributeType | null {
70
+ if (!parts.length) {
71
+ return item;
72
+ }
73
+
74
+ const [currentPart, ...otherParts] = parts;
75
+
76
+ // Promitive attributes can be returned directly
77
+ if (typeof item === "string") {
78
+ return item;
79
+ }
80
+
81
+ // Complex attributes
82
+ if (Array.isArray(item)) {
83
+ if (item[0] === "set" || item[0] === "list") {
84
+ if (currentPart === "[]") {
85
+ return findType(item[1], otherParts);
86
+ }
87
+ // Trying to access a property on a list
88
+ return null;
89
+ }
90
+
91
+ if (item[0] === "object") {
92
+ if (currentPart === "[]") {
93
+ // Trying to access a property on a list
94
+ return null;
95
+ }
96
+
97
+ return findType(item[1][currentPart], otherParts);
98
+ }
99
+
100
+ if (item[0] === "map") {
101
+ // We don't care what the key is
102
+ return findType(item[1], otherParts);
103
+ }
104
+
105
+ // Unknown type
106
+ return null;
107
+ }
108
+
109
+ // If we are not in an attribute, we can ignore the [] (since max_item=1 parts don't have [], so we just ignore it)
110
+ if (currentPart === "[]") {
111
+ return findType(item, otherParts);
112
+ }
113
+
114
+ // Block
115
+ if (item.block) {
116
+ // Find block type in block
117
+ if (item.block.block_types) {
118
+ const blockType = item.block.block_types[currentPart];
119
+ if (blockType) {
120
+ return findType(blockType, otherParts);
121
+ }
122
+ }
123
+
124
+ // Find attribute in block
125
+ if (item.block.attributes) {
126
+ const attribute = item.block.attributes[currentPart];
127
+ if (attribute && attribute.type) {
128
+ return findType(attribute.type, otherParts);
129
+ }
130
+ }
131
+ }
132
+
133
+ // Could not find the type
134
+ return null;
135
+ }
136
+
137
+ export function getTypeAtPath(
138
+ schema: ProviderSchema,
139
+ path: string,
140
+ ): Schema | BlockType | AttributeType | null {
141
+ const resourceSchema = getResourceAtPath(schema, path);
142
+
143
+ if (!resourceSchema) {
144
+ return null;
145
+ }
146
+ const { resource, parts } = resourceSchema;
147
+ return findType(resource, parts);
148
+ }
149
+
150
+ export const isMapAttribute = (
151
+ attribute: Schema | AttributeType | BlockType | null,
152
+ ) => (Array.isArray(attribute) ? attribute[0] === "map" : false);
153
+
154
+ export function getDesiredType(
155
+ scope: ProgramScope,
156
+ path: string,
157
+ ): AttributeType {
158
+ const attributeOrBlockType = getTypeAtPath(scope.providerSchema, path);
159
+
160
+ // Attribute type is not defined
161
+ if (!attributeOrBlockType) {
162
+ return "dynamic";
163
+ }
164
+
165
+ // Primitive attribute type
166
+ if (typeof attributeOrBlockType === "string") {
167
+ return attributeOrBlockType;
168
+ }
169
+
170
+ // Complex attribute type
171
+ if (Array.isArray(attributeOrBlockType)) {
172
+ return attributeOrBlockType;
173
+ }
174
+
175
+ // Schema
176
+ if ("version" in attributeOrBlockType) {
177
+ return "dynamic";
178
+ }
179
+
180
+ // Block type
181
+ return "dynamic";
182
+ }
package/src/types.ts ADDED
@@ -0,0 +1,58 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import { TerraformProviderGenerator } from "@cdktn/provider-generator";
4
+ import { ProviderSchema } from "@cdktn/commons";
5
+
6
+ export type TerraformResourceBlock = unknown;
7
+ export type AttributePath = string;
8
+ export type ProgramScope = {
9
+ providerSchema: ProviderSchema;
10
+ providerGenerator: Record<string, TerraformProviderGenerator>;
11
+ constructs: Set<string>;
12
+ variables: Record<
13
+ string,
14
+ {
15
+ resource: string;
16
+ variableName: string;
17
+ }
18
+ >;
19
+ // Temporary flag to indicate if we need to import the cdktf library to access the token class
20
+ hasTokenBasedTypeCoercion: boolean;
21
+ nodeIds: string[]; // temporarily added until replaced
22
+ importables: ImportableConstruct[]; // records all imports for the conversion
23
+ topLevelConfig: Record<string, AttributePath>;
24
+ };
25
+
26
+ export type ResourceScope = ProgramScope & {
27
+ forEachIteratorName?: string; // set if a for_each is used in this resource
28
+ countIteratorName?: string; // set if a count is used in this resource
29
+ withinOverrideExpression?: boolean; // set if we are currently within an override expression
30
+ scopedVariables?: Record<string, string>; // set if we are currently within an dynamic block expression
31
+ };
32
+
33
+ export type Reference = {
34
+ start: number;
35
+ end: number;
36
+ referencee: { id: string; full: string }; // identifier for resource
37
+ useFqn?: boolean;
38
+ isVariable?: boolean;
39
+ };
40
+
41
+ export type DynamicBlock = {
42
+ path: string;
43
+ for_each: string;
44
+ content: TerraformResourceBlock;
45
+ scopedVar: string;
46
+ };
47
+
48
+ export type IteratorVariableReference = {
49
+ start: number;
50
+ end: number;
51
+ value: string;
52
+ };
53
+
54
+ export type ImportableConstruct = {
55
+ provider: string;
56
+ constructName: string;
57
+ namespace?: string;
58
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,19 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import camelcase from "camelcase";
4
+
5
+ export { logger } from "@cdktn/commons";
6
+
7
+ export const fileBugCommentText = `This is likely a bug in cdktn. Please report it at https://github.com/open-constructs/cdk-terrain/issues/new?assignees=&labels=bug&template=bug-report.md&title=.`;
8
+
9
+ export const camelCase = (str: string) => camelcase(str.replace(/[-/]/g, "_"));
10
+ export const pascalCase = (str: string) =>
11
+ camelcase(str.replace(/[-/]/g, "_"), { pascalCase: true });
12
+
13
+ export function uniqueId(set: Set<string>, key: string): string {
14
+ if (set.has(key)) {
15
+ return uniqueId(set, `${key}_${set.size}`);
16
+ }
17
+ set.add(key);
18
+ return key;
19
+ }
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import * as t from "@babel/types";
7
+ import { ProgramScope, Reference } from "./types";
8
+ import { camelCase, pascalCase } from "./utils";
9
+ import { sanitizeClassOrNamespaceName } from "@cdktn/provider-generator";
10
+ import { getFullProviderName } from "./provider";
11
+ import reservedWords from "reserved-words";
12
+
13
+ export function referenceToVariableName(
14
+ scope: ProgramScope,
15
+ ref: Reference,
16
+ ): string {
17
+ const parts = ref.referencee.id.split(".");
18
+ const resource = parts[0] === "data" ? `${parts[0]}.${parts[1]}` : parts[0];
19
+ const name = parts[0] === "data" ? parts[2] : parts[1];
20
+ return variableName(scope, resource, name);
21
+ }
22
+
23
+ function validVarName(name: string) {
24
+ if (reservedWords.check(name)) {
25
+ return `${name}Var`;
26
+ }
27
+
28
+ if (!Number.isNaN(parseInt(name[0], 10))) {
29
+ return `d${name}`;
30
+ }
31
+
32
+ return name;
33
+ }
34
+
35
+ function getUniqueName(scope: ProgramScope, provider: string, type: string) {
36
+ // early abort on cdktf
37
+ if (provider === "cdktf") {
38
+ return pascalCase(type.replace("cdktf_", ""));
39
+ }
40
+ // early abort on cdktn
41
+ if (provider === "cdktn") {
42
+ return pascalCase(type.replace("cdktn_", ""));
43
+ }
44
+
45
+ if (provider === "NullProvider") {
46
+ return pascalCase(type.replace("NullProvider_", ""));
47
+ }
48
+
49
+ // Special handling for provider blocks, e.g. aws_AwsProvider
50
+ if (type === `${pascalCase(provider)}Provider`) {
51
+ return sanitizeClassOrNamespaceName(type, true);
52
+ }
53
+
54
+ const fullProviderName = getFullProviderName(scope.providerSchema, provider);
55
+ if (fullProviderName && scope.providerGenerator[fullProviderName]) {
56
+ return scope.providerGenerator[fullProviderName]?.getClassNameForResource(
57
+ type,
58
+ );
59
+ } else {
60
+ // If we can not find the class name for a resource the caller needs to find a sensible default
61
+ return null;
62
+ }
63
+ }
64
+
65
+ function getResourceNamespace(
66
+ scope: ProgramScope,
67
+ provider: string,
68
+ resource: string,
69
+ isDataSource: boolean,
70
+ type: string,
71
+ ) {
72
+ // happens e.g. for references to cdktn.TerraformStack (and similar) in generated code
73
+ if (provider === "cdktn") {
74
+ return undefined;
75
+ }
76
+
77
+ // e.g. awsProvider -> provider
78
+ if (
79
+ resource === pascalCase(`${provider}_provider`) ||
80
+ (provider === "NullProvider" && resource === "NullProvider")
81
+ ) {
82
+ return "provider";
83
+ }
84
+
85
+ const fullProviderName = getFullProviderName(scope.providerSchema, provider);
86
+
87
+ if (fullProviderName && scope.providerGenerator[fullProviderName]) {
88
+ return camelCase(
89
+ scope.providerGenerator[fullProviderName]?.getNamespaceNameForResource(
90
+ type.replace(/\./g, "_"),
91
+ ),
92
+ );
93
+ }
94
+
95
+ if (isDataSource) {
96
+ return camelCase(
97
+ sanitizeClassOrNamespaceName(`data_${provider}_${resource}`),
98
+ );
99
+ }
100
+
101
+ return camelCase(sanitizeClassOrNamespaceName(resource));
102
+ }
103
+
104
+ export function constructAst(
105
+ scope: ProgramScope,
106
+ type: string,
107
+ isModuleImport: boolean,
108
+ ) {
109
+ if (isModuleImport) {
110
+ return t.memberExpression(t.identifier(type), t.identifier(type));
111
+ }
112
+
113
+ if (type.startsWith("var.")) {
114
+ scope.importables.push({
115
+ provider: "cdktn",
116
+ constructName: "TerraformVariable",
117
+ });
118
+
119
+ return t.identifier("TerraformVariable");
120
+ }
121
+
122
+ if (type === "terraform.data") {
123
+ scope.importables.push({
124
+ constructName: "DataResource",
125
+ provider: "cdktn",
126
+ });
127
+ return t.identifier("DataResource");
128
+ }
129
+
130
+ // resources or data sources
131
+ if (!type.includes("./") && type.includes(".")) {
132
+ const parts = type.split(".");
133
+ if (parts[0] === "data") {
134
+ const [, provider, resource] = parts;
135
+
136
+ const namespace = getResourceNamespace(
137
+ scope,
138
+ provider,
139
+ resource,
140
+ true,
141
+ type,
142
+ );
143
+ const resourceName =
144
+ getUniqueName(scope, provider, parts.join("_")) ||
145
+ pascalCase(
146
+ sanitizeClassOrNamespaceName(`data_${provider}_${resource}`),
147
+ );
148
+
149
+ scope.importables.push({
150
+ provider: provider,
151
+ constructName: resourceName,
152
+ namespace,
153
+ });
154
+
155
+ if (namespace) {
156
+ return t.identifier(resourceName); // e.g. DataAwsInstance
157
+ }
158
+
159
+ return t.identifier(resourceName); // e.g. DataAwsNatGateway
160
+ }
161
+
162
+ const [provider, resource] = parts;
163
+ const namespace = getResourceNamespace(
164
+ scope,
165
+ provider,
166
+ resource,
167
+ false,
168
+ type,
169
+ );
170
+ const resourceName =
171
+ getUniqueName(scope, provider, parts.join("_")) ||
172
+ pascalCase(sanitizeClassOrNamespaceName(resource));
173
+
174
+ scope.importables.push({
175
+ provider: provider,
176
+ constructName: resourceName,
177
+ namespace,
178
+ });
179
+
180
+ if (namespace) {
181
+ return t.identifier(resourceName); // e.g. Instance
182
+ }
183
+
184
+ return t.identifier(resourceName); // e.g. BigQueryTable
185
+ }
186
+
187
+ return t.identifier(pascalCase(type));
188
+ }
189
+
190
+ export function variableName(
191
+ scope: ProgramScope,
192
+ resource: string,
193
+ name: string,
194
+ ): string {
195
+ const consistentResourceName = resource.replace(/\./g, "_");
196
+ // name collision, we need to prefix the name
197
+ if (scope.variables[name]) {
198
+ if (consistentResourceName === scope.variables[name].resource) {
199
+ return scope.variables[name].variableName;
200
+ }
201
+
202
+ // we only cache one per name
203
+ return validVarName(camelCase([resource, name].join("_")));
204
+ }
205
+
206
+ const variableName = validVarName(camelCase(name));
207
+
208
+ scope.variables[name] = {
209
+ variableName,
210
+ resource: consistentResourceName,
211
+ };
212
+
213
+ return variableName;
214
+ }
@@ -0,0 +1,70 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`backends local backend snapshot typescript 1`] = `
4
+ "import { Construct } from "constructs";
5
+ import { LocalBackend, TerraformStack } from "cdktn";
6
+ class MyConvertedCode extends TerraformStack {
7
+ constructor(scope: Construct, name: string) {
8
+ super(scope, name);
9
+ new LocalBackend(this, {
10
+ path: "relative/path/to/terraform.tfstate",
11
+ });
12
+ }
13
+ }
14
+ "
15
+ `;
16
+
17
+ exports[`backends remote backend snapshot typescript 1`] = `
18
+ "import { Construct } from "constructs";
19
+ import { RemoteBackend, TerraformStack } from "cdktn";
20
+ class MyConvertedCode extends TerraformStack {
21
+ constructor(scope: Construct, name: string) {
22
+ super(scope, name);
23
+ new RemoteBackend(this, {
24
+ hostname: "app.terraform.io",
25
+ organization: "company",
26
+ workspaces: [
27
+ {
28
+ name: "my-app-prod",
29
+ },
30
+ ],
31
+ });
32
+ }
33
+ }
34
+ "
35
+ `;
36
+
37
+ exports[`backends remote state snapshot typescript 1`] = `
38
+ "import { Construct } from "constructs";
39
+ import { DataTerraformRemoteState, TerraformStack } from "cdktn";
40
+ class MyConvertedCode extends TerraformStack {
41
+ constructor(scope: Construct, name: string) {
42
+ super(scope, name);
43
+ new DataTerraformRemoteState(this, "vpc", {
44
+ organization: "hashicorp",
45
+ workspaces: [
46
+ {
47
+ name: "vpc-prod",
48
+ },
49
+ ],
50
+ });
51
+ }
52
+ }
53
+ "
54
+ `;
55
+
56
+ exports[`backends remote state types snapshot typescript 1`] = `
57
+ "import { Construct } from "constructs";
58
+ import { DataTerraformRemoteStateS3, TerraformStack } from "cdktn";
59
+ class MyConvertedCode extends TerraformStack {
60
+ constructor(scope: Construct, name: string) {
61
+ super(scope, name);
62
+ new DataTerraformRemoteStateS3(this, "s3", {
63
+ bucket: "mybucket",
64
+ key: "path/to/my/key",
65
+ region: "us-east-1",
66
+ });
67
+ }
68
+ }
69
+ "
70
+ `;
@@ -0,0 +1,37 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`externals handle simple external data snapshot typescript 1`] = `
4
+ "import { Construct } from "constructs";
5
+ import {
6
+ VariableType,
7
+ TerraformVariable,
8
+ TerraformOutput,
9
+ Fn,
10
+ TerraformStack,
11
+ } from "cdktn";
12
+ /*
13
+ * Provider bindings are generated by running \`cdktn get\`.
14
+ * See https://cdktn.io/docs/concepts/providers#import-providers for more details.
15
+ */
16
+ import { DataExternal } from "./.gen/providers/external/data-external";
17
+ import { ExternalProvider } from "./.gen/providers/external/provider";
18
+ class MyConvertedCode extends TerraformStack {
19
+ constructor(scope: Construct, name: string) {
20
+ super(scope, name);
21
+ /*Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK.
22
+ You can read more about this at https://cdktn.io/docs/concepts/variables-and-outputs#input-variables*/
23
+ new ExternalProvider(this, "external", {});
24
+ const fargateRegion = new TerraformVariable(this, "fargate_region", {
25
+ default: "us-east-1",
26
+ type: VariableType.STRING,
27
+ });
28
+ const dataExternalThumbprint = new DataExternal(this, "thumbprint", {
29
+ program: ["\${path.module}/oidc_thumbprint.sh", fargateRegion.value],
30
+ });
31
+ new TerraformOutput(this, "foo", {
32
+ value: Fn.lookupNested(dataExternalThumbprint, ["result", "thumbprint"]),
33
+ });
34
+ }
35
+ }
36
+ "
37
+ `;