@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.
- package/LICENSE +355 -0
- package/README.md +1 -1
- package/build/__tests__/expressions.test.js +10 -19
- package/build/__tests__/functions.test.js +8 -18
- package/build/__tests__/testHelpers.js +3 -2
- package/build/coerceType.js +11 -21
- package/build/dynamic-blocks.js +3 -3
- package/build/expressions.js +13 -22
- package/build/function-bindings/functions.generated.js +2 -2
- package/build/generation.js +24 -34
- package/build/index.js +15 -25
- package/build/iteration.js +7 -6
- package/build/jsii-rosetta-workarounds.js +6 -5
- package/build/partialCode.js +11 -20
- package/build/provider.js +4 -3
- package/build/references.js +6 -5
- package/build/schema.js +8 -18
- package/build/terraformSchema.js +4 -4
- package/build/utils.js +3 -3
- package/build/variables.js +12 -21
- package/package.json +20 -17
- package/package.sh +1 -1
- package/src/__tests__/coerceType.test.ts +207 -0
- package/src/__tests__/expressionToTs.test.ts +1167 -0
- package/src/__tests__/expressions.test.ts +541 -0
- package/src/__tests__/findExpressionType.test.ts +112 -0
- package/src/__tests__/functions.test.ts +768 -0
- package/src/__tests__/generation.test.ts +72 -0
- package/src/__tests__/jsii-rosetta-workarounds.test.ts +145 -0
- package/src/__tests__/partialCode.test.ts +432 -0
- package/src/__tests__/terraformSchema.test.ts +107 -0
- package/src/__tests__/testHelpers.ts +11 -0
- package/src/coerceType.ts +261 -0
- package/src/dynamic-blocks.ts +61 -0
- package/src/expressions.ts +968 -0
- package/src/function-bindings/functions.generated.ts +1139 -0
- package/src/function-bindings/functions.ts +104 -0
- package/src/generation.ts +1189 -0
- package/src/index.ts +584 -0
- package/src/iteration.ts +156 -0
- package/src/jsii-rosetta-workarounds.ts +145 -0
- package/src/partialCode.ts +132 -0
- package/src/provider.ts +60 -0
- package/src/references.ts +193 -0
- package/src/schema.ts +74 -0
- package/src/terraformSchema.ts +182 -0
- package/src/types.ts +58 -0
- package/src/utils.ts +19 -0
- package/src/variables.ts +214 -0
- package/test/__snapshots__/backends.test.ts.snap +70 -0
- package/test/__snapshots__/externals.test.ts.snap +37 -0
- package/test/__snapshots__/granular-imports.test.ts.snap +180 -0
- package/test/__snapshots__/imports.test.ts.snap +159 -0
- package/test/__snapshots__/iteration.test.ts.snap +532 -0
- package/test/__snapshots__/jsiiLanguage.test.ts.snap +347 -0
- package/test/__snapshots__/locals.test.ts.snap +55 -0
- package/test/__snapshots__/modules.test.ts.snap +127 -0
- package/test/__snapshots__/outputs.test.ts.snap +77 -0
- package/test/__snapshots__/partialCode.test.ts.snap +120 -0
- package/test/__snapshots__/provider.test.ts.snap +128 -0
- package/test/__snapshots__/references.test.ts.snap +376 -0
- package/test/__snapshots__/resource-meta-properties.test.ts.snap +342 -0
- package/test/__snapshots__/resources.test.ts.snap +613 -0
- package/test/__snapshots__/tfExpressions.test.ts.snap +537 -0
- package/test/__snapshots__/typeCoercion.test.ts.snap +253 -0
- package/test/__snapshots__/variables.test.ts.snap +150 -0
- package/test/backends.test.ts +75 -0
- package/test/convertProject.test.ts +257 -0
- package/test/externals.test.ts +35 -0
- package/test/globalSetup.ts +224 -0
- package/test/globalTeardown.ts +11 -0
- package/test/granular-imports.test.ts +161 -0
- package/test/hcl2cdk.test.ts +88 -0
- package/test/helpers/convert.ts +543 -0
- package/test/helpers/tmp.ts +25 -0
- package/test/imports.test.ts +141 -0
- package/test/iteration.test.ts +342 -0
- package/test/jsiiLanguage.test.ts +73 -0
- package/test/locals.test.ts +47 -0
- package/test/modules.test.ts +143 -0
- package/test/outputs.test.ts +69 -0
- package/test/partialCode.test.ts +25 -0
- package/test/provider.test.ts +106 -0
- package/test/references.test.ts +287 -0
- package/test/resource-meta-properties.test.ts +288 -0
- package/test/resources.test.ts +551 -0
- package/test/tfExpressions.test.ts +300 -0
- package/test/typeCoercion.test.ts +154 -0
- package/test/variables.test.ts +96 -0
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as t from "@babel/types";
|
|
7
|
+
import { AttributeType } from "@cdktn/commons";
|
|
8
|
+
import { coerceType } from "../coerceType";
|
|
9
|
+
import { functionsMap } from "../function-bindings/functions";
|
|
10
|
+
import { ProgramScope } from "../types";
|
|
11
|
+
import { astToCode } from "./testHelpers";
|
|
12
|
+
|
|
13
|
+
type BaseThing = {
|
|
14
|
+
type: string;
|
|
15
|
+
children: Thing[];
|
|
16
|
+
meta?: object;
|
|
17
|
+
range?: unknown; // optional as we don't care about it
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type FunctionCall = BaseThing & {
|
|
21
|
+
type: "function";
|
|
22
|
+
meta: {
|
|
23
|
+
name: string;
|
|
24
|
+
expandedFinalArgument?: boolean; // optional as we don't care about it
|
|
25
|
+
closeParenRange?: unknown; // optional as we don't care about it
|
|
26
|
+
openParenRange?: unknown; // optional as we don't care about it
|
|
27
|
+
nameRange?: unknown; // optional as we don't care about it
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type TemplateWrap = BaseThing & {
|
|
32
|
+
type: "TemplateWrap";
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type Template = BaseThing & {
|
|
36
|
+
type: "Template";
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type LiteralValue = BaseThing & {
|
|
40
|
+
type: "LiteralValue";
|
|
41
|
+
meta: {
|
|
42
|
+
type: "string";
|
|
43
|
+
value: string; // this is available in other "Things" too but we only need it here yet
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type ScopeTraversal = BaseThing & {
|
|
48
|
+
type: "ScopeTraversal";
|
|
49
|
+
meta: {
|
|
50
|
+
traversal: {
|
|
51
|
+
segment: string;
|
|
52
|
+
range?: unknown; // optional as we don't care about it
|
|
53
|
+
}[];
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const scope: ProgramScope = {
|
|
58
|
+
providerSchema: {},
|
|
59
|
+
providerGenerator: {},
|
|
60
|
+
constructs: new Set(),
|
|
61
|
+
variables: {},
|
|
62
|
+
hasTokenBasedTypeCoercion: false,
|
|
63
|
+
nodeIds: [],
|
|
64
|
+
importables: [],
|
|
65
|
+
topLevelConfig: {},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type Thing =
|
|
69
|
+
| FunctionCall
|
|
70
|
+
| TemplateWrap
|
|
71
|
+
| Template
|
|
72
|
+
| ScopeTraversal
|
|
73
|
+
| LiteralValue;
|
|
74
|
+
|
|
75
|
+
// '${replace(module.foo.output, "-", var.bar)}'
|
|
76
|
+
// from https://github.com/hashicorp/terraform-cdk/pull/2729
|
|
77
|
+
const dummy2: Thing = {
|
|
78
|
+
children: [
|
|
79
|
+
{
|
|
80
|
+
children: [
|
|
81
|
+
{
|
|
82
|
+
children: [],
|
|
83
|
+
meta: {
|
|
84
|
+
traversal: [
|
|
85
|
+
{
|
|
86
|
+
range: {
|
|
87
|
+
End: {
|
|
88
|
+
Byte: 16,
|
|
89
|
+
Column: 16,
|
|
90
|
+
Line: 0,
|
|
91
|
+
},
|
|
92
|
+
Filename: "",
|
|
93
|
+
Start: {
|
|
94
|
+
Byte: 10,
|
|
95
|
+
Column: 10,
|
|
96
|
+
Line: 0,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
segment: "module",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
range: {
|
|
103
|
+
End: {
|
|
104
|
+
Byte: 20,
|
|
105
|
+
Column: 20,
|
|
106
|
+
Line: 0,
|
|
107
|
+
},
|
|
108
|
+
Filename: "",
|
|
109
|
+
Start: {
|
|
110
|
+
Byte: 16,
|
|
111
|
+
Column: 16,
|
|
112
|
+
Line: 0,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
segment: "foo",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
range: {
|
|
119
|
+
End: {
|
|
120
|
+
Byte: 27,
|
|
121
|
+
Column: 27,
|
|
122
|
+
Line: 0,
|
|
123
|
+
},
|
|
124
|
+
Filename: "",
|
|
125
|
+
Start: {
|
|
126
|
+
Byte: 20,
|
|
127
|
+
Column: 20,
|
|
128
|
+
Line: 0,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
segment: "output",
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
range: {
|
|
136
|
+
end: {
|
|
137
|
+
byte: 27,
|
|
138
|
+
column: 27,
|
|
139
|
+
line: 0,
|
|
140
|
+
},
|
|
141
|
+
start: {
|
|
142
|
+
byte: 10,
|
|
143
|
+
column: 10,
|
|
144
|
+
line: 0,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
type: "ScopeTraversal",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
children: [
|
|
151
|
+
{
|
|
152
|
+
children: [],
|
|
153
|
+
meta: {
|
|
154
|
+
type: "string",
|
|
155
|
+
value: "-",
|
|
156
|
+
},
|
|
157
|
+
range: {
|
|
158
|
+
end: {
|
|
159
|
+
byte: 31,
|
|
160
|
+
column: 31,
|
|
161
|
+
line: 0,
|
|
162
|
+
},
|
|
163
|
+
start: {
|
|
164
|
+
byte: 30,
|
|
165
|
+
column: 30,
|
|
166
|
+
line: 0,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
type: "LiteralValue",
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
range: {
|
|
173
|
+
end: {
|
|
174
|
+
byte: 31,
|
|
175
|
+
column: 31,
|
|
176
|
+
line: 0,
|
|
177
|
+
},
|
|
178
|
+
start: {
|
|
179
|
+
byte: 30,
|
|
180
|
+
column: 30,
|
|
181
|
+
line: 0,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
type: "Template",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
children: [],
|
|
188
|
+
meta: {
|
|
189
|
+
traversal: [
|
|
190
|
+
{
|
|
191
|
+
range: {
|
|
192
|
+
End: {
|
|
193
|
+
Byte: 37,
|
|
194
|
+
Column: 37,
|
|
195
|
+
Line: 0,
|
|
196
|
+
},
|
|
197
|
+
Filename: "",
|
|
198
|
+
Start: {
|
|
199
|
+
Byte: 34,
|
|
200
|
+
Column: 34,
|
|
201
|
+
Line: 0,
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
segment: "var",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
range: {
|
|
208
|
+
End: {
|
|
209
|
+
Byte: 41,
|
|
210
|
+
Column: 41,
|
|
211
|
+
Line: 0,
|
|
212
|
+
},
|
|
213
|
+
Filename: "",
|
|
214
|
+
Start: {
|
|
215
|
+
Byte: 37,
|
|
216
|
+
Column: 37,
|
|
217
|
+
Line: 0,
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
segment: "bar",
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
range: {
|
|
225
|
+
end: {
|
|
226
|
+
byte: 41,
|
|
227
|
+
column: 41,
|
|
228
|
+
line: 0,
|
|
229
|
+
},
|
|
230
|
+
start: {
|
|
231
|
+
byte: 34,
|
|
232
|
+
column: 34,
|
|
233
|
+
line: 0,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
type: "ScopeTraversal",
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
meta: {
|
|
240
|
+
closeParenRange: {
|
|
241
|
+
end: {
|
|
242
|
+
byte: 42,
|
|
243
|
+
column: 42,
|
|
244
|
+
line: 0,
|
|
245
|
+
},
|
|
246
|
+
start: {
|
|
247
|
+
byte: 41,
|
|
248
|
+
column: 41,
|
|
249
|
+
line: 0,
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
expandedFinalArgument: false,
|
|
253
|
+
name: "replace",
|
|
254
|
+
nameRange: {
|
|
255
|
+
end: {
|
|
256
|
+
byte: 9,
|
|
257
|
+
column: 9,
|
|
258
|
+
line: 0,
|
|
259
|
+
},
|
|
260
|
+
start: {
|
|
261
|
+
byte: 2,
|
|
262
|
+
column: 2,
|
|
263
|
+
line: 0,
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
openParenRange: {
|
|
267
|
+
end: {
|
|
268
|
+
byte: 10,
|
|
269
|
+
column: 10,
|
|
270
|
+
line: 0,
|
|
271
|
+
},
|
|
272
|
+
start: {
|
|
273
|
+
byte: 9,
|
|
274
|
+
column: 9,
|
|
275
|
+
line: 0,
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
range: {
|
|
280
|
+
end: {
|
|
281
|
+
byte: 10,
|
|
282
|
+
column: 10,
|
|
283
|
+
line: 0,
|
|
284
|
+
},
|
|
285
|
+
start: {
|
|
286
|
+
byte: 2,
|
|
287
|
+
column: 2,
|
|
288
|
+
line: 0,
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
type: "function",
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
range: {
|
|
295
|
+
end: {
|
|
296
|
+
byte: 43,
|
|
297
|
+
column: 43,
|
|
298
|
+
line: 0,
|
|
299
|
+
},
|
|
300
|
+
start: {
|
|
301
|
+
byte: 0,
|
|
302
|
+
column: 0,
|
|
303
|
+
line: 0,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
type: "TemplateWrap",
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
describe("bindings for Terraform functions", () => {
|
|
310
|
+
it("should convert Terraform AST into TS AST", () => {
|
|
311
|
+
expect(
|
|
312
|
+
astToCode(terraformThingToTs(scope, dummy2, "dynamic")),
|
|
313
|
+
).toMatchInlineSnapshot(
|
|
314
|
+
`"Fn.replace(TodoReference-module-foo-output, "-", TodoReference-var-bar)"`,
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("should convert Terraform AST into TS AST for overriden function name", () => {
|
|
319
|
+
expect(
|
|
320
|
+
astToCode(
|
|
321
|
+
terraformThingToTs(
|
|
322
|
+
scope,
|
|
323
|
+
{
|
|
324
|
+
type: "function",
|
|
325
|
+
meta: {
|
|
326
|
+
name: "length",
|
|
327
|
+
},
|
|
328
|
+
children: [
|
|
329
|
+
{
|
|
330
|
+
type: "ScopeTraversal",
|
|
331
|
+
meta: {
|
|
332
|
+
traversal: [
|
|
333
|
+
{
|
|
334
|
+
segment: "var",
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
segment: "list",
|
|
338
|
+
},
|
|
339
|
+
],
|
|
340
|
+
},
|
|
341
|
+
children: [],
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
},
|
|
345
|
+
"number",
|
|
346
|
+
),
|
|
347
|
+
),
|
|
348
|
+
).toMatchInlineSnapshot(`"Fn.lengthOf(TodoReference-var-list)"`);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it("should convert Terraform AST into TS AST for overriden function with variadic args for optional params", () => {
|
|
352
|
+
expect(
|
|
353
|
+
astToCode(
|
|
354
|
+
terraformThingToTs(
|
|
355
|
+
scope,
|
|
356
|
+
{
|
|
357
|
+
type: "function",
|
|
358
|
+
meta: {
|
|
359
|
+
name: "bcrypt",
|
|
360
|
+
},
|
|
361
|
+
children: [
|
|
362
|
+
{
|
|
363
|
+
type: "ScopeTraversal",
|
|
364
|
+
meta: {
|
|
365
|
+
traversal: [
|
|
366
|
+
{
|
|
367
|
+
segment: "var",
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
segment: "str",
|
|
371
|
+
},
|
|
372
|
+
],
|
|
373
|
+
},
|
|
374
|
+
children: [],
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
type: "ScopeTraversal",
|
|
378
|
+
meta: {
|
|
379
|
+
traversal: [
|
|
380
|
+
{
|
|
381
|
+
segment: "var",
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
segment: "cost",
|
|
385
|
+
},
|
|
386
|
+
],
|
|
387
|
+
},
|
|
388
|
+
children: [],
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
},
|
|
392
|
+
"string",
|
|
393
|
+
),
|
|
394
|
+
),
|
|
395
|
+
).toMatchInlineSnapshot(
|
|
396
|
+
`"Fn.bcrypt(TodoReference-var-str, TodoReference-var-cost)"`,
|
|
397
|
+
);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it("should convert Terraform AST into TS AST for overriden function with variadic args for optional params that are not passed", () => {
|
|
401
|
+
expect(
|
|
402
|
+
astToCode(
|
|
403
|
+
terraformThingToTs(
|
|
404
|
+
scope,
|
|
405
|
+
{
|
|
406
|
+
type: "function",
|
|
407
|
+
meta: {
|
|
408
|
+
name: "bcrypt",
|
|
409
|
+
},
|
|
410
|
+
children: [
|
|
411
|
+
{
|
|
412
|
+
type: "ScopeTraversal",
|
|
413
|
+
meta: {
|
|
414
|
+
traversal: [
|
|
415
|
+
{
|
|
416
|
+
segment: "var",
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
segment: "str",
|
|
420
|
+
},
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
children: [],
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
},
|
|
427
|
+
"string",
|
|
428
|
+
),
|
|
429
|
+
),
|
|
430
|
+
).toMatchInlineSnapshot(`"Fn.bcrypt(TodoReference-var-str)"`);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it("should convert Terraform AST into TS AST for function with variadic param", () => {
|
|
434
|
+
expect(
|
|
435
|
+
astToCode(
|
|
436
|
+
terraformThingToTs(
|
|
437
|
+
scope,
|
|
438
|
+
{
|
|
439
|
+
type: "function",
|
|
440
|
+
meta: {
|
|
441
|
+
name: "try",
|
|
442
|
+
},
|
|
443
|
+
children: [
|
|
444
|
+
{
|
|
445
|
+
type: "ScopeTraversal",
|
|
446
|
+
meta: {
|
|
447
|
+
traversal: [
|
|
448
|
+
{
|
|
449
|
+
segment: "var",
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
segment: "strA",
|
|
453
|
+
},
|
|
454
|
+
],
|
|
455
|
+
},
|
|
456
|
+
children: [],
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
type: "ScopeTraversal",
|
|
460
|
+
meta: {
|
|
461
|
+
traversal: [
|
|
462
|
+
{
|
|
463
|
+
segment: "var",
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
segment: "strB",
|
|
467
|
+
},
|
|
468
|
+
],
|
|
469
|
+
},
|
|
470
|
+
children: [],
|
|
471
|
+
},
|
|
472
|
+
],
|
|
473
|
+
},
|
|
474
|
+
"dynamic",
|
|
475
|
+
),
|
|
476
|
+
),
|
|
477
|
+
).toMatchInlineSnapshot(
|
|
478
|
+
`"Fn.try([TodoReference-var-strA, TodoReference-var-strB])"`,
|
|
479
|
+
);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it("should convert Terraform AST into TS AST for join function with single list param", () => {
|
|
483
|
+
expect(
|
|
484
|
+
astToCode(
|
|
485
|
+
terraformThingToTs(
|
|
486
|
+
scope,
|
|
487
|
+
{
|
|
488
|
+
type: "function",
|
|
489
|
+
meta: {
|
|
490
|
+
name: "join",
|
|
491
|
+
},
|
|
492
|
+
children: [
|
|
493
|
+
{
|
|
494
|
+
type: "ScopeTraversal",
|
|
495
|
+
meta: {
|
|
496
|
+
traversal: [
|
|
497
|
+
{
|
|
498
|
+
segment: "var",
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
segment: "str",
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
},
|
|
505
|
+
children: [],
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
type: "ScopeTraversal",
|
|
509
|
+
meta: {
|
|
510
|
+
traversal: [
|
|
511
|
+
{
|
|
512
|
+
segment: "var",
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
segment: "list",
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
},
|
|
519
|
+
children: [],
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
},
|
|
523
|
+
"string",
|
|
524
|
+
),
|
|
525
|
+
),
|
|
526
|
+
).toMatchInlineSnapshot(
|
|
527
|
+
`"Fn.join(TodoReference-var-str, TodoReference-var-list)"`,
|
|
528
|
+
);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it("should convert Terraform AST into TS AST for join function with multiple list params", () => {
|
|
532
|
+
expect(
|
|
533
|
+
astToCode(
|
|
534
|
+
terraformThingToTs(
|
|
535
|
+
scope,
|
|
536
|
+
{
|
|
537
|
+
type: "function",
|
|
538
|
+
meta: {
|
|
539
|
+
name: "join",
|
|
540
|
+
},
|
|
541
|
+
children: [
|
|
542
|
+
{
|
|
543
|
+
type: "ScopeTraversal",
|
|
544
|
+
meta: {
|
|
545
|
+
traversal: [
|
|
546
|
+
{
|
|
547
|
+
segment: "var",
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
segment: "str",
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
},
|
|
554
|
+
children: [],
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
type: "ScopeTraversal",
|
|
558
|
+
meta: {
|
|
559
|
+
traversal: [
|
|
560
|
+
{
|
|
561
|
+
segment: "var",
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
segment: "listA",
|
|
565
|
+
},
|
|
566
|
+
],
|
|
567
|
+
},
|
|
568
|
+
children: [],
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
type: "ScopeTraversal",
|
|
572
|
+
meta: {
|
|
573
|
+
traversal: [
|
|
574
|
+
{
|
|
575
|
+
segment: "var",
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
segment: "listB",
|
|
579
|
+
},
|
|
580
|
+
],
|
|
581
|
+
},
|
|
582
|
+
children: [],
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
},
|
|
586
|
+
"string",
|
|
587
|
+
),
|
|
588
|
+
),
|
|
589
|
+
).toMatchInlineSnapshot(
|
|
590
|
+
`"Fn.join(TodoReference-var-str, Token.asList(Fn.concat([TodoReference-var-listA, TodoReference-var-listB])))"`,
|
|
591
|
+
);
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it("should throw if not enough parameters were passed", () => {
|
|
595
|
+
expect(() =>
|
|
596
|
+
astToCode(
|
|
597
|
+
terraformThingToTs(
|
|
598
|
+
scope,
|
|
599
|
+
{
|
|
600
|
+
type: "function",
|
|
601
|
+
meta: {
|
|
602
|
+
name: "bcrypt",
|
|
603
|
+
},
|
|
604
|
+
children: [],
|
|
605
|
+
},
|
|
606
|
+
"string",
|
|
607
|
+
),
|
|
608
|
+
),
|
|
609
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
610
|
+
`"Terraform function call to "bcrypt" is not valid! Parameter at index 0 of type string is not optional but received no value. The following parameters were passed: []"`,
|
|
611
|
+
);
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
// TODO: tests for type coercion
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
function terraformThingToTs(
|
|
618
|
+
scope: ProgramScope,
|
|
619
|
+
tfAst: Thing,
|
|
620
|
+
targetType: AttributeType | undefined,
|
|
621
|
+
): t.Expression {
|
|
622
|
+
switch (tfAst.type) {
|
|
623
|
+
case "function": {
|
|
624
|
+
return terraformFunctionCallToTs(scope, tfAst, targetType);
|
|
625
|
+
}
|
|
626
|
+
case "TemplateWrap": {
|
|
627
|
+
// If there's just one child, we can skip them
|
|
628
|
+
if (tfAst.children.length === 1) {
|
|
629
|
+
return terraformThingToTs(scope, tfAst.children[0], targetType);
|
|
630
|
+
}
|
|
631
|
+
throw new Error(
|
|
632
|
+
"TemplateWrap with not exactly one child is not supported yet: " +
|
|
633
|
+
tfAst.children,
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
case "ScopeTraversal": {
|
|
637
|
+
return terraformScopeTraversalToTs(tfAst, targetType);
|
|
638
|
+
}
|
|
639
|
+
case "Template": {
|
|
640
|
+
return terraformTemplateToTs(scope, tfAst, targetType);
|
|
641
|
+
}
|
|
642
|
+
case "LiteralValue": {
|
|
643
|
+
return terraformLiteralValueToTs(tfAst, targetType);
|
|
644
|
+
}
|
|
645
|
+
default:
|
|
646
|
+
throw new Error("Unsupported type: " + (tfAst as any).type);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function terraformScopeTraversalToTs(
|
|
651
|
+
tfAst: ScopeTraversal,
|
|
652
|
+
_targetType: AttributeType | undefined,
|
|
653
|
+
): t.Expression {
|
|
654
|
+
return t.identifier(
|
|
655
|
+
"TodoReference-" + tfAst.meta.traversal.map((t) => t.segment).join("-"),
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function terraformTemplateToTs(
|
|
660
|
+
scope: ProgramScope,
|
|
661
|
+
tfAst: Template,
|
|
662
|
+
targetType: AttributeType | undefined,
|
|
663
|
+
): t.Expression {
|
|
664
|
+
if (tfAst.children.length === 1) {
|
|
665
|
+
return terraformThingToTs(scope, tfAst.children[0], targetType);
|
|
666
|
+
}
|
|
667
|
+
throw new Error("Template currently only supports exactly one child");
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
function terraformLiteralValueToTs(
|
|
671
|
+
tfAst: LiteralValue,
|
|
672
|
+
targetType: AttributeType | undefined,
|
|
673
|
+
): t.Expression {
|
|
674
|
+
const literalExpression = t.stringLiteral(tfAst.meta.value);
|
|
675
|
+
return coerceType(
|
|
676
|
+
// TODO: scope should be passed instead, even if coerceType won't need it probably
|
|
677
|
+
{
|
|
678
|
+
constructs: new Set(),
|
|
679
|
+
hasTokenBasedTypeCoercion: false,
|
|
680
|
+
providerGenerator: {},
|
|
681
|
+
providerSchema: {},
|
|
682
|
+
variables: {},
|
|
683
|
+
nodeIds: [],
|
|
684
|
+
importables: [],
|
|
685
|
+
topLevelConfig: {},
|
|
686
|
+
},
|
|
687
|
+
literalExpression,
|
|
688
|
+
tfAst.meta.type,
|
|
689
|
+
targetType,
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function terraformFunctionCallToTs(
|
|
694
|
+
scope: ProgramScope,
|
|
695
|
+
tfAst: FunctionCall,
|
|
696
|
+
targetType: AttributeType | undefined,
|
|
697
|
+
): t.Expression {
|
|
698
|
+
const { name } = tfAst.meta;
|
|
699
|
+
|
|
700
|
+
const mapping = functionsMap[name];
|
|
701
|
+
if (!mapping) {
|
|
702
|
+
throw new Error(`Mapping not found for function: ${name}`);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
if (mapping.transformer) {
|
|
706
|
+
const newTfAst = mapping.transformer(tfAst);
|
|
707
|
+
if (newTfAst !== tfAst)
|
|
708
|
+
return terraformFunctionCallToTs(scope, newTfAst, targetType);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
scope.importables.push({
|
|
712
|
+
constructName: "Fn",
|
|
713
|
+
provider: "cdktn",
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
const callee = t.memberExpression(
|
|
717
|
+
t.identifier("Fn"),
|
|
718
|
+
t.identifier(mapping.name),
|
|
719
|
+
);
|
|
720
|
+
|
|
721
|
+
const args: t.Expression[] = [];
|
|
722
|
+
mapping.parameters.forEach((param, idx) => {
|
|
723
|
+
if (param.variadic) {
|
|
724
|
+
// return an array with all remaining children (each mapped accordingly)
|
|
725
|
+
args.push(
|
|
726
|
+
t.arrayExpression(
|
|
727
|
+
tfAst.children
|
|
728
|
+
.slice(idx)
|
|
729
|
+
.map((child) => terraformThingToTs(scope, child, param.type)),
|
|
730
|
+
),
|
|
731
|
+
);
|
|
732
|
+
} else {
|
|
733
|
+
const child = tfAst.children[idx];
|
|
734
|
+
if (child) {
|
|
735
|
+
args.push(terraformThingToTs(scope, child, param.type));
|
|
736
|
+
} else if (!param.optional) {
|
|
737
|
+
throw new Error(
|
|
738
|
+
`Terraform function call to "${name}" is not valid! Parameter at index ${idx} of type ${
|
|
739
|
+
param.type
|
|
740
|
+
} is not optional but received no value. The following parameters were passed: ${JSON.stringify(
|
|
741
|
+
tfAst.children,
|
|
742
|
+
)}`,
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
const returnType = mapping.returnType;
|
|
749
|
+
|
|
750
|
+
const callExpression = t.callExpression(callee, args);
|
|
751
|
+
|
|
752
|
+
return coerceType(
|
|
753
|
+
// TODO: scope should be passed instead, even if coerceType won't need it probably
|
|
754
|
+
{
|
|
755
|
+
constructs: new Set(),
|
|
756
|
+
hasTokenBasedTypeCoercion: false,
|
|
757
|
+
providerGenerator: {},
|
|
758
|
+
providerSchema: {},
|
|
759
|
+
variables: {},
|
|
760
|
+
nodeIds: [],
|
|
761
|
+
importables: [],
|
|
762
|
+
topLevelConfig: {},
|
|
763
|
+
},
|
|
764
|
+
callExpression,
|
|
765
|
+
returnType,
|
|
766
|
+
targetType,
|
|
767
|
+
);
|
|
768
|
+
}
|