@cdktn/provider-generator 0.24.0-pre.9 → 0.24.0-pre.90

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 (124) hide show
  1. package/.spec.swcrc +22 -0
  2. package/LICENSE +355 -0
  3. package/README.md +1 -1
  4. package/build/__tests__/edge-provider-schema/builder.d.ts +9 -3
  5. package/build/__tests__/edge-provider-schema/builder.js +6 -3
  6. package/build/__tests__/edge-provider-schema/cli.js +8 -3
  7. package/build/__tests__/edge-provider-schema/index.js +119 -1
  8. package/build/__tests__/provider.test.js +4 -1
  9. package/build/get/__tests__/generator/ephemeral-resources.test.d.ts +2 -0
  10. package/build/get/__tests__/generator/ephemeral-resources.test.js +49 -0
  11. package/build/get/__tests__/generator/module-generator.test.js +12 -12
  12. package/build/get/__tests__/generator/provider-functions.test.d.ts +2 -0
  13. package/build/get/__tests__/generator/provider-functions.test.js +176 -0
  14. package/build/get/__tests__/generator/provider-source-matching.test.d.ts +2 -0
  15. package/build/get/__tests__/generator/provider-source-matching.test.js +45 -0
  16. package/build/get/__tests__/generator/provider.test.js +9 -1
  17. package/build/get/__tests__/generator/supported-stored-classes.test.d.ts +2 -0
  18. package/build/get/__tests__/generator/supported-stored-classes.test.js +137 -0
  19. package/build/get/__tests__/generator/types.test.js +44 -1
  20. package/build/get/__tests__/generator/write-only.test.d.ts +2 -0
  21. package/build/get/__tests__/generator/write-only.test.js +65 -0
  22. package/build/get/__tests__/target-versions.test.d.ts +2 -0
  23. package/build/get/__tests__/target-versions.test.js +171 -0
  24. package/build/get/constructs-maker.d.ts +8 -1
  25. package/build/get/constructs-maker.js +46 -10
  26. package/build/get/generator/emitter/attributes-emitter.d.ts +13 -2
  27. package/build/get/generator/emitter/attributes-emitter.js +71 -5
  28. package/build/get/generator/emitter/index.d.ts +1 -0
  29. package/build/get/generator/emitter/index.js +2 -1
  30. package/build/get/generator/emitter/provider-functions-emitter.d.ts +11 -0
  31. package/build/get/generator/emitter/provider-functions-emitter.js +94 -0
  32. package/build/get/generator/emitter/resource-emitter.d.ts +5 -1
  33. package/build/get/generator/emitter/resource-emitter.js +83 -7
  34. package/build/get/generator/emitter/struct-emitter.js +10 -10
  35. package/build/get/generator/models/attribute-model.d.ts +4 -0
  36. package/build/get/generator/models/attribute-model.js +50 -4
  37. package/build/get/generator/models/attribute-type-model.d.ts +24 -0
  38. package/build/get/generator/models/attribute-type-model.js +91 -5
  39. package/build/get/generator/models/index.d.ts +1 -0
  40. package/build/get/generator/models/index.js +2 -1
  41. package/build/get/generator/models/provider-function-model.d.ts +102 -0
  42. package/build/get/generator/models/provider-function-model.js +667 -0
  43. package/build/get/generator/models/resource-model.d.ts +3 -0
  44. package/build/get/generator/models/resource-model.js +13 -4
  45. package/build/get/generator/models/struct.d.ts +2 -0
  46. package/build/get/generator/models/struct.js +6 -2
  47. package/build/get/generator/models/supported-stored-classes.d.ts +5 -0
  48. package/build/get/generator/models/supported-stored-classes.js +86 -0
  49. package/build/get/generator/module-generator.js +3 -3
  50. package/build/get/generator/provider-generator.d.ts +2 -0
  51. package/build/get/generator/provider-generator.js +41 -6
  52. package/build/get/generator/resource-parser.js +3 -1
  53. package/jest.config.js +16 -9
  54. package/package.json +28 -27
  55. package/package.sh +1 -1
  56. package/src/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +4 -0
  57. package/src/__tests__/__snapshots__/provider.test.ts.snap +2828 -2828
  58. package/src/__tests__/edge-provider-schema/builder.ts +201 -0
  59. package/src/__tests__/edge-provider-schema/cli.ts +51 -0
  60. package/src/__tests__/edge-provider-schema/index.ts +284 -0
  61. package/src/__tests__/edge-provider-schema.test.ts +24 -0
  62. package/src/__tests__/provider.test.ts +183 -0
  63. package/src/get/__tests__/constructs-maker.test.ts +118 -0
  64. package/src/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +5 -5
  65. package/src/get/__tests__/generator/__snapshots__/ephemeral-resources.test.ts.snap +524 -0
  66. package/src/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +3310 -3310
  67. package/src/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +355 -355
  68. package/src/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +8 -8
  69. package/src/get/__tests__/generator/__snapshots__/provider-functions.test.ts.snap +444 -0
  70. package/src/get/__tests__/generator/__snapshots__/provider.test.ts.snap +8 -8
  71. package/src/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +126 -126
  72. package/src/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +17 -17
  73. package/src/get/__tests__/generator/__snapshots__/types.test.ts.snap +201 -52
  74. package/src/get/__tests__/generator/__snapshots__/write-only.test.ts.snap +262 -0
  75. package/src/get/__tests__/generator/complex-computed-types.test.ts +28 -0
  76. package/src/get/__tests__/generator/deep-nested-attributes.test.ts +56 -0
  77. package/src/get/__tests__/generator/description-escaping.test.ts +84 -0
  78. package/src/get/__tests__/generator/empty-provider-resources.test.ts +26 -0
  79. package/src/get/__tests__/generator/ephemeral-resources.test.ts +46 -0
  80. package/src/get/__tests__/generator/export-sharding.test.ts +169 -0
  81. package/src/get/__tests__/generator/fixtures/deeply-nested-collections.test.fixture.json +129 -0
  82. package/src/get/__tests__/generator/fixtures/ephemeral-resources.test.fixture.json +160 -0
  83. package/src/get/__tests__/generator/fixtures/provider-functions-collision.test.fixture.json +31 -0
  84. package/src/get/__tests__/generator/fixtures/provider-functions-synthetic.test.fixture.json +192 -0
  85. package/src/get/__tests__/generator/fixtures/provider-functions.test.fixture.json +170 -0
  86. package/src/get/__tests__/generator/fixtures/write-only.test.fixture.json +58 -0
  87. package/src/get/__tests__/generator/import-style.test.ts +129 -0
  88. package/src/get/__tests__/generator/module-generator.test.ts +528 -0
  89. package/src/get/__tests__/generator/nested-types.test.ts +54 -0
  90. package/src/get/__tests__/generator/provider-functions.test.ts +262 -0
  91. package/src/get/__tests__/generator/provider-source-matching.test.ts +84 -0
  92. package/src/get/__tests__/generator/provider.test.ts +59 -0
  93. package/src/get/__tests__/generator/resource-types.test.ts +118 -0
  94. package/src/get/__tests__/generator/skipped-attributes.test.ts +72 -0
  95. package/src/get/__tests__/generator/supported-stored-classes.test.ts +147 -0
  96. package/src/get/__tests__/generator/types.test.ts +686 -0
  97. package/src/get/__tests__/generator/versions-file.test.ts +72 -0
  98. package/src/get/__tests__/generator/write-only.test.ts +71 -0
  99. package/src/get/__tests__/target-versions.test.ts +206 -0
  100. package/src/get/__tests__/util.ts +75 -0
  101. package/src/get/constructs-maker.ts +885 -0
  102. package/src/get/generator/custom-defaults.ts +493 -0
  103. package/src/get/generator/emitter/attributes-emitter.ts +316 -0
  104. package/src/get/generator/emitter/index.ts +6 -0
  105. package/src/get/generator/emitter/provider-functions-emitter.ts +117 -0
  106. package/src/get/generator/emitter/resource-emitter.ts +330 -0
  107. package/src/get/generator/emitter/struct-emitter.ts +683 -0
  108. package/src/get/generator/loop-detection.ts +81 -0
  109. package/src/get/generator/models/attribute-model.ts +273 -0
  110. package/src/get/generator/models/attribute-type-model.ts +560 -0
  111. package/src/get/generator/models/index.ts +8 -0
  112. package/src/get/generator/models/provider-function-model.ts +872 -0
  113. package/src/get/generator/models/resource-model.ts +183 -0
  114. package/src/get/generator/models/scope.ts +54 -0
  115. package/src/get/generator/models/struct.ts +124 -0
  116. package/src/get/generator/models/supported-stored-classes.ts +88 -0
  117. package/src/get/generator/module-generator.ts +234 -0
  118. package/src/get/generator/provider-generator.ts +428 -0
  119. package/src/get/generator/resource-parser.ts +764 -0
  120. package/src/get/generator/sanitized-comments.ts +49 -0
  121. package/src/get/generator/skipped-attributes.ts +27 -0
  122. package/src/index.ts +40 -0
  123. package/src/util.ts +26 -0
  124. package/tsconfig.json +1 -2
@@ -0,0 +1,686 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ import { TerraformProviderGenerator } from "../../generator/provider-generator";
6
+ import { CodeMaker } from "codemaker";
7
+ import { createTmpHelper } from "../util";
8
+
9
+ const tmp = createTmpHelper();
10
+
11
+ test("computed optional complex attribute", async () => {
12
+ const code = new CodeMaker();
13
+ const workdir = tmp("computed-complex-option.test");
14
+ const spec = JSON.parse(
15
+ fs.readFileSync(
16
+ path.join(
17
+ __dirname,
18
+ "fixtures",
19
+ "computed-optional-complex.test.fixture.json",
20
+ ),
21
+ "utf-8",
22
+ ),
23
+ );
24
+ new TerraformProviderGenerator(code, spec).generateAll();
25
+ await code.save(workdir);
26
+
27
+ const output = fs.readFileSync(
28
+ path.join(workdir, "providers/aws/computed-optional-complex/index.ts"),
29
+ "utf-8",
30
+ );
31
+ expect(output).toMatchSnapshot();
32
+ });
33
+
34
+ test("computed complex attribute", async () => {
35
+ const code = new CodeMaker();
36
+ const workdir = tmp("computed-complex.test");
37
+ const spec = JSON.parse(
38
+ fs.readFileSync(
39
+ path.join(__dirname, "fixtures", "computed-complex.test.fixture.json"),
40
+ "utf-8",
41
+ ),
42
+ );
43
+ new TerraformProviderGenerator(code, spec).generateAll();
44
+ await code.save(workdir);
45
+
46
+ const output = fs.readFileSync(
47
+ path.join(workdir, "providers/aws/computed-complex/index.ts"),
48
+ "utf-8",
49
+ );
50
+ expect(output).toMatchSnapshot();
51
+ });
52
+
53
+ test("computed complex nested attribute", async () => {
54
+ const code = new CodeMaker();
55
+ const workdir = tmp("computed-complex-nested.test");
56
+ const spec = JSON.parse(
57
+ fs.readFileSync(
58
+ path.join(
59
+ __dirname,
60
+ "fixtures",
61
+ "computed-complex-nested.test.fixture.json",
62
+ ),
63
+ "utf-8",
64
+ ),
65
+ );
66
+ new TerraformProviderGenerator(code, spec).generateAll();
67
+ await code.save(workdir);
68
+
69
+ const output = fs.readFileSync(
70
+ path.join(workdir, "providers/aws/computed-complex-nested/index.ts"),
71
+ "utf-8",
72
+ );
73
+ expect(output).toMatchSnapshot();
74
+ });
75
+
76
+ test("string list attribute", async () => {
77
+ const code = new CodeMaker();
78
+ const workdir = tmp("string-list.test");
79
+ const spec = JSON.parse(
80
+ fs.readFileSync(
81
+ path.join(__dirname, "fixtures", "string-list.test.fixture.json"),
82
+ "utf-8",
83
+ ),
84
+ );
85
+ new TerraformProviderGenerator(code, spec).generateAll();
86
+ await code.save(workdir);
87
+
88
+ const output = fs.readFileSync(
89
+ path.join(workdir, "providers/aws/string-list/index.ts"),
90
+ "utf-8",
91
+ );
92
+ expect(output).toMatchSnapshot();
93
+ });
94
+
95
+ test("number list attribute", async () => {
96
+ const code = new CodeMaker();
97
+ const workdir = tmp("number-list.test");
98
+ const spec = JSON.parse(
99
+ fs.readFileSync(
100
+ path.join(__dirname, "fixtures", "number-list.test.fixture.json"),
101
+ "utf-8",
102
+ ),
103
+ );
104
+ new TerraformProviderGenerator(code, spec).generateAll();
105
+ await code.save(workdir);
106
+
107
+ const output = fs.readFileSync(
108
+ path.join(workdir, "providers/aws/number-list/index.ts"),
109
+ "utf-8",
110
+ );
111
+ expect(output).toMatchSnapshot();
112
+ });
113
+
114
+ test("boolean list attribute", async () => {
115
+ const code = new CodeMaker();
116
+ const workdir = tmp("boolean-list.test");
117
+ const spec = JSON.parse(
118
+ fs.readFileSync(
119
+ path.join(__dirname, "fixtures", "boolean-list.test.fixture.json"),
120
+ "utf-8",
121
+ ),
122
+ );
123
+ new TerraformProviderGenerator(code, spec).generateAll();
124
+ await code.save(workdir);
125
+
126
+ const output = fs.readFileSync(
127
+ path.join(workdir, "providers/aws/boolean-list/index.ts"),
128
+ "utf-8",
129
+ );
130
+ expect(output).toMatchSnapshot();
131
+ });
132
+
133
+ test("string map attribute", async () => {
134
+ const code = new CodeMaker();
135
+ const workdir = tmp("string-map.test");
136
+ const spec = JSON.parse(
137
+ fs.readFileSync(
138
+ path.join(__dirname, "fixtures", "string-map.test.fixture.json"),
139
+ "utf-8",
140
+ ),
141
+ );
142
+ new TerraformProviderGenerator(code, spec).generateAll();
143
+ await code.save(workdir);
144
+
145
+ const output = fs.readFileSync(
146
+ path.join(workdir, "providers/aws/string-map/index.ts"),
147
+ "utf-8",
148
+ );
149
+ expect(output).toMatchSnapshot();
150
+ });
151
+
152
+ test("number map attribute", async () => {
153
+ const code = new CodeMaker();
154
+ const workdir = tmp("number-map.test");
155
+ const spec = JSON.parse(
156
+ fs.readFileSync(
157
+ path.join(__dirname, "fixtures", "number-map.test.fixture.json"),
158
+ "utf-8",
159
+ ),
160
+ );
161
+ new TerraformProviderGenerator(code, spec).generateAll();
162
+ await code.save(workdir);
163
+
164
+ const output = fs.readFileSync(
165
+ path.join(workdir, "providers/aws/number-map/index.ts"),
166
+ "utf-8",
167
+ );
168
+ expect(output).toMatchSnapshot();
169
+ });
170
+
171
+ test("boolean map attribute", async () => {
172
+ const code = new CodeMaker();
173
+ const workdir = tmp("boolean-map.test");
174
+ const spec = JSON.parse(
175
+ fs.readFileSync(
176
+ path.join(__dirname, "fixtures", "boolean-map.test.fixture.json"),
177
+ "utf-8",
178
+ ),
179
+ );
180
+ new TerraformProviderGenerator(code, spec).generateAll();
181
+ await code.save(workdir);
182
+
183
+ const output = fs.readFileSync(
184
+ path.join(workdir, "providers/aws/boolean-map/index.ts"),
185
+ "utf-8",
186
+ );
187
+ expect(output).toMatchSnapshot();
188
+ });
189
+
190
+ test("deeply nested block types", async () => {
191
+ const code = new CodeMaker();
192
+ const workdir = tmp("block-types.test");
193
+ const spec = JSON.parse(
194
+ fs.readFileSync(
195
+ path.join(
196
+ __dirname,
197
+ "fixtures",
198
+ "deeply-nested-block-types.test.fixture.json",
199
+ ),
200
+ "utf-8",
201
+ ),
202
+ );
203
+ new TerraformProviderGenerator(code, spec).generateAll();
204
+ await code.save(workdir);
205
+
206
+ const output = fs.readFileSync(
207
+ path.join(workdir, "providers/aws/deeply-nested-block-types/index.ts"),
208
+ "utf-8",
209
+ );
210
+ expect(output).toMatchSnapshot();
211
+ });
212
+
213
+ test("single block type", async () => {
214
+ const code = new CodeMaker();
215
+ const workdir = tmp("single-block-type.test");
216
+ const spec = JSON.parse(
217
+ fs.readFileSync(
218
+ path.join(__dirname, "fixtures", "single-block-type.test.fixture.json"),
219
+ "utf-8",
220
+ ),
221
+ );
222
+ new TerraformProviderGenerator(code, spec).generateAll();
223
+ await code.save(workdir);
224
+
225
+ const output = fs.readFileSync(
226
+ path.join(workdir, "providers/aws/single-block-type/index.ts"),
227
+ "utf-8",
228
+ );
229
+ expect(output).toMatchSnapshot();
230
+ });
231
+
232
+ test("set / list block type", async () => {
233
+ const code = new CodeMaker();
234
+ const workdir = tmp("set-list-block.test");
235
+ const spec = JSON.parse(
236
+ fs.readFileSync(
237
+ path.join(__dirname, "fixtures", "block-type-set-list.test.fixture.json"),
238
+ "utf-8",
239
+ ),
240
+ );
241
+ new TerraformProviderGenerator(code, spec).generateAll();
242
+ await code.save(workdir);
243
+
244
+ const output = fs.readFileSync(
245
+ path.join(workdir, "providers/aws/block-type-set-list/index.ts"),
246
+ "utf-8",
247
+ );
248
+ expect(output).toMatchSnapshot();
249
+ });
250
+
251
+ test("computed nested complex list block type", async () => {
252
+ const code = new CodeMaker();
253
+ const workdir = tmp("nested-computed-list-block.test");
254
+ const spec = JSON.parse(
255
+ fs.readFileSync(
256
+ path.join(
257
+ __dirname,
258
+ "fixtures",
259
+ "block-type-nested-computed-list.test.fixture.json",
260
+ ),
261
+ "utf-8",
262
+ ),
263
+ );
264
+ new TerraformProviderGenerator(code, spec).generateAll();
265
+ await code.save(workdir);
266
+
267
+ const output = fs.readFileSync(
268
+ path.join(
269
+ workdir,
270
+ "providers/aws/block-type-nested-computed-list/index.ts",
271
+ ),
272
+ "utf-8",
273
+ );
274
+ expect(output).toMatchSnapshot();
275
+ });
276
+
277
+ test("primitive string", async () => {
278
+ const code = new CodeMaker();
279
+ const workdir = tmp("primitive-string.test");
280
+ const spec = JSON.parse(
281
+ fs.readFileSync(
282
+ path.join(__dirname, "fixtures", "primitive-string.test.fixture.json"),
283
+ "utf-8",
284
+ ),
285
+ );
286
+ new TerraformProviderGenerator(code, spec).generateAll();
287
+ await code.save(workdir);
288
+
289
+ const output = fs.readFileSync(
290
+ path.join(workdir, "providers/aws/primitive-string/index.ts"),
291
+ "utf-8",
292
+ );
293
+ expect(output).toMatchSnapshot();
294
+ });
295
+
296
+ test("primitive number", async () => {
297
+ const code = new CodeMaker();
298
+ const workdir = tmp("primitive-number.test");
299
+ const spec = JSON.parse(
300
+ fs.readFileSync(
301
+ path.join(__dirname, "fixtures", "primitive-number.test.fixture.json"),
302
+ "utf-8",
303
+ ),
304
+ );
305
+ new TerraformProviderGenerator(code, spec).generateAll();
306
+ await code.save(workdir);
307
+
308
+ const output = fs.readFileSync(
309
+ path.join(workdir, "providers/aws/primitive-number/index.ts"),
310
+ "utf-8",
311
+ );
312
+ expect(output).toMatchSnapshot();
313
+ });
314
+
315
+ test("primitive boolean", async () => {
316
+ const code = new CodeMaker();
317
+ const workdir = tmp("primitive-boolean.test");
318
+ const spec = JSON.parse(
319
+ fs.readFileSync(
320
+ path.join(__dirname, "fixtures", "primitive-boolean.test.fixture.json"),
321
+ "utf-8",
322
+ ),
323
+ );
324
+ new TerraformProviderGenerator(code, spec).generateAll();
325
+ await code.save(workdir);
326
+
327
+ const output = fs.readFileSync(
328
+ path.join(workdir, "providers/aws/primitive-boolean/index.ts"),
329
+ "utf-8",
330
+ );
331
+ expect(output).toMatchSnapshot();
332
+ });
333
+
334
+ test("primitive dynamic", async () => {
335
+ const code = new CodeMaker();
336
+ const workdir = tmp("primitive-dynamic.test");
337
+ const spec = JSON.parse(
338
+ fs.readFileSync(
339
+ path.join(__dirname, "fixtures", "primitive-dynamic.test.fixture.json"),
340
+ "utf-8",
341
+ ),
342
+ );
343
+ new TerraformProviderGenerator(code, spec).generateAll();
344
+ await code.save(workdir);
345
+
346
+ const output = fs.readFileSync(
347
+ path.join(workdir, "providers/aws/primitive-dynamic/index.ts"),
348
+ "utf-8",
349
+ );
350
+ expect(output).toMatchSnapshot();
351
+ });
352
+
353
+ test("ignored attributes", async () => {
354
+ const code = new CodeMaker();
355
+ const workdir = tmp("ignored-attributes.test");
356
+ const spec = JSON.parse(
357
+ fs.readFileSync(
358
+ path.join(__dirname, "fixtures", "ignored-attributes.test.fixture.json"),
359
+ "utf-8",
360
+ ),
361
+ );
362
+ new TerraformProviderGenerator(code, spec).generateAll();
363
+ await code.save(workdir);
364
+
365
+ const output = fs.readFileSync(
366
+ path.join(workdir, "providers/aws/ignored-attributes/index.ts"),
367
+ "utf-8",
368
+ );
369
+ expect(output).toMatchSnapshot();
370
+ });
371
+
372
+ test("incompatible attribute names", async () => {
373
+ const code = new CodeMaker();
374
+ const workdir = tmp("incompatible-attribute-names.test");
375
+ const spec = JSON.parse(
376
+ fs.readFileSync(
377
+ path.join(
378
+ __dirname,
379
+ "fixtures",
380
+ "incompatible-attribute-names.test.fixture.json",
381
+ ),
382
+ "utf-8",
383
+ ),
384
+ );
385
+ new TerraformProviderGenerator(code, spec).generateAll();
386
+ await code.save(workdir);
387
+
388
+ const output = fs.readFileSync(
389
+ path.join(workdir, "providers/aws/incompatible-attribute-names/index.ts"),
390
+ "utf-8",
391
+ );
392
+ expect(output).toMatchSnapshot();
393
+ });
394
+
395
+ test("incompatible resource names", async () => {
396
+ const code = new CodeMaker();
397
+ const workdir = tmp("incompatible-resource-names.test");
398
+ const spec = JSON.parse(
399
+ fs.readFileSync(
400
+ path.join(
401
+ __dirname,
402
+ "fixtures",
403
+ "incompatible-resource-names.test.fixture.json",
404
+ ),
405
+ "utf-8",
406
+ ),
407
+ );
408
+ new TerraformProviderGenerator(code, spec).generateAll();
409
+ await code.save(workdir);
410
+
411
+ const files = fs.readdirSync(path.join(workdir, "providers/test"));
412
+ const topLevelFiles = ["index.ts", "lazy-index.ts"];
413
+ expect(files).toMatchInlineSnapshot(`
414
+ [
415
+ "function-resource",
416
+ "index.ts",
417
+ "lazy-index.ts",
418
+ "license-resource",
419
+ "object-resource",
420
+ "provider-resource",
421
+ "static-resource",
422
+ "string-resource",
423
+ "version-resource",
424
+ ]
425
+ `);
426
+
427
+ for (const file of files) {
428
+ const output = fs.readFileSync(
429
+ path.join(
430
+ workdir,
431
+ "providers/test/",
432
+ file,
433
+ topLevelFiles.includes(file) ? "" : "index.ts",
434
+ ),
435
+ "utf-8",
436
+ );
437
+ expect(output).toMatchSnapshot(file); // use filename as snapshot indicator to not depend on order of files (e.g. if new file appears)
438
+ }
439
+ });
440
+
441
+ test("list of string map attribute", async () => {
442
+ const code = new CodeMaker();
443
+ const workdir = tmp("list-of-string-map.test");
444
+ const spec = JSON.parse(
445
+ fs.readFileSync(
446
+ path.join(__dirname, "fixtures", "list-of-string-map.test.fixture.json"),
447
+ "utf-8",
448
+ ),
449
+ );
450
+ new TerraformProviderGenerator(code, spec).generateAll();
451
+ await code.save(workdir);
452
+
453
+ const output = fs.readFileSync(
454
+ path.join(workdir, "providers/aws/list-of-string-map/index.ts"),
455
+ "utf-8",
456
+ );
457
+ expect(output).toMatchSnapshot();
458
+ });
459
+
460
+ test("map of string list attribute", async () => {
461
+ const code = new CodeMaker();
462
+ const workdir = tmp("map-of-string-list.test");
463
+ const spec = JSON.parse(
464
+ fs.readFileSync(
465
+ path.join(__dirname, "fixtures", "map-of-string-list.test.fixture.json"),
466
+ "utf-8",
467
+ ),
468
+ );
469
+ new TerraformProviderGenerator(code, spec).generateAll();
470
+ await code.save(workdir);
471
+
472
+ const output = fs.readFileSync(
473
+ path.join(workdir, "providers/aws/map-of-string-list/index.ts"),
474
+ "utf-8",
475
+ );
476
+ expect(output).toMatchSnapshot();
477
+ });
478
+
479
+ test("reset and input name conflicts", async () => {
480
+ const code = new CodeMaker();
481
+ const workdir = tmp("name-conflict.test");
482
+ const spec = JSON.parse(
483
+ fs.readFileSync(
484
+ path.join(__dirname, "fixtures", "name-conflict.test.fixture.json"),
485
+ "utf-8",
486
+ ),
487
+ );
488
+ new TerraformProviderGenerator(code, spec).generateAll();
489
+ await code.save(workdir);
490
+
491
+ const output = fs.readFileSync(
492
+ path.join(workdir, "providers/aws/name-conflict/index.ts"),
493
+ "utf-8",
494
+ );
495
+ expect(output).toMatchSnapshot();
496
+ });
497
+
498
+ test("list of list attributes", async () => {
499
+ const code = new CodeMaker();
500
+ const workdir = tmp("list-list-object.test");
501
+ const spec = JSON.parse(
502
+ fs.readFileSync(
503
+ path.join(__dirname, "fixtures", "list-list-object.test.fixture.json"),
504
+ "utf-8",
505
+ ),
506
+ );
507
+ new TerraformProviderGenerator(code, spec).generateAll();
508
+ await code.save(workdir);
509
+
510
+ const output = fs.readFileSync(
511
+ path.join(workdir, "providers/test/complex/index.ts"),
512
+ "utf-8",
513
+ );
514
+ expect(output).toMatchSnapshot();
515
+ });
516
+
517
+ test("list of list of strings", async () => {
518
+ const code = new CodeMaker();
519
+ const workdir = tmp("list-list-string.test");
520
+ const spec = JSON.parse(
521
+ fs.readFileSync(
522
+ path.join(__dirname, "fixtures", "list-list-string.test.fixture.json"),
523
+ "utf-8",
524
+ ),
525
+ );
526
+ new TerraformProviderGenerator(code, spec).generateAll();
527
+ await code.save(workdir);
528
+
529
+ // const resourceOutput = fs.readFileSync(
530
+ // path.join(workdir, "providers/test/airbyte-connection/index.ts"),
531
+ // "utf-8"
532
+ // );
533
+ // expect(resourceOutput).toMatchSnapshot();
534
+
535
+ const datasourceOutput = fs.readFileSync(
536
+ path.join(
537
+ workdir,
538
+ "providers/test/data-airbyte-source-schema-catalog/index.ts",
539
+ ),
540
+ "utf-8",
541
+ );
542
+ expect(datasourceOutput).toMatchSnapshot();
543
+ });
544
+
545
+ test("map of map of string attribute", async () => {
546
+ const code = new CodeMaker();
547
+ const workdir = tmp("map-of-map-of-string.test");
548
+ const spec = JSON.parse(
549
+ fs.readFileSync(
550
+ path.join(
551
+ __dirname,
552
+ "fixtures",
553
+ "map-of-map-of-string.test.fixture.json",
554
+ ),
555
+ "utf-8",
556
+ ),
557
+ );
558
+ new TerraformProviderGenerator(code, spec).generateAll();
559
+ await code.save(workdir);
560
+
561
+ const output = fs.readFileSync(
562
+ path.join(workdir, "providers/aws/map-of-map-of-string/index.ts"),
563
+ "utf-8",
564
+ );
565
+ expect(output).toMatchSnapshot();
566
+ });
567
+
568
+ test("case-insensitive base name collision", async () => {
569
+ const code = new CodeMaker();
570
+ const workdir = tmp("case-insensitive-base-name-collision.test");
571
+ const spec = JSON.parse(
572
+ fs.readFileSync(
573
+ path.join(
574
+ __dirname,
575
+ "fixtures",
576
+ "case-insensitive-base-name-collision.test.fixture.json",
577
+ ),
578
+ "utf-8",
579
+ ),
580
+ );
581
+ new TerraformProviderGenerator(code, spec).generateAll();
582
+ await code.save(workdir);
583
+
584
+ const files = fs.readdirSync(path.join(workdir, "providers/oci"));
585
+ const topLevelFiles = ["index.ts", "lazy-index.ts"];
586
+
587
+ // Verify that colliding base names are disambiguated with a "-a" suffix.
588
+ expect(files).toContain("load-balancer-backend-set");
589
+ expect(files).toContain("load-balancer-backendset-a");
590
+
591
+ expect(files).toContain("data-oci-load-balancer-backend-sets");
592
+ expect(files).toContain("data-oci-load-balancer-backendsets-a");
593
+
594
+ // No two directories should collide case-insensitively
595
+ const lowercaseFiles = files.map((f) => f.toLowerCase());
596
+ const uniqueLowercaseFiles = [...new Set(lowercaseFiles)];
597
+ expect(lowercaseFiles).toEqual(uniqueLowercaseFiles);
598
+
599
+ for (const file of files) {
600
+ const output = fs.readFileSync(
601
+ path.join(
602
+ workdir,
603
+ "providers/oci/",
604
+ file,
605
+ topLevelFiles.includes(file) ? "" : "index.ts",
606
+ ),
607
+ "utf-8",
608
+ );
609
+ expect(output).toMatchSnapshot(file);
610
+ }
611
+ });
612
+
613
+ test("deeply nested (unsupported) collection attribute types", async () => {
614
+ // Regression test for https://github.com/open-constructs/cdk-terrain/issues/11:
615
+ // computed attributes whose type nests list/set/map more than two levels deep (e.g.
616
+ // map(map(list(string)))) must not generate a reference to a "cdktn.*" stored class
617
+ // that doesn't exist (e.g. "StringListMapMap"). Instead of falling straight back to a
618
+ // plain, untyped getter, the generator collapses these into the nearest typed
619
+ // "Any"-wrapper that does exist (e.g. "AnyMapMap"), preserving typed navigation for the
620
+ // outer layers. Only shapes with no available stored class at all fall back to a plain
621
+ // getter.
622
+ const code = new CodeMaker();
623
+ const workdir = tmp("deeply-nested-collections.test");
624
+ const spec = JSON.parse(
625
+ fs.readFileSync(
626
+ path.join(
627
+ __dirname,
628
+ "fixtures",
629
+ "deeply-nested-collections.test.fixture.json",
630
+ ),
631
+ "utf-8",
632
+ ),
633
+ );
634
+ new TerraformProviderGenerator(code, spec).generateAll();
635
+ await code.save(workdir);
636
+
637
+ const output = fs.readFileSync(
638
+ path.join(
639
+ workdir,
640
+ "providers/test/data-deeply-nested-collections/index.ts",
641
+ ),
642
+ "utf-8",
643
+ );
644
+ expect(output).toMatchSnapshot();
645
+
646
+ // None of the unsupported nested attributes should reference a non-existent "cdktn.*"
647
+ // wrapper class.
648
+ expect(output).not.toContain("StringListMapMap");
649
+ expect(output).not.toContain("StringMapMapList");
650
+ expect(output).not.toContain("NumberListMapList");
651
+ expect(output).not.toContain("StringListMapMapMap");
652
+
653
+ // Unsupported triple nestings collapse to the nearest typed "Any"-wrapper instead of
654
+ // falling back to a plain getter.
655
+ expect(output).toContain('new cdktn.AnyMapMap(this, "map_map_list_string")');
656
+ expect(output).toContain(
657
+ 'new cdktn.AnyMapList(this, "list_map_map_string", false)',
658
+ );
659
+ expect(output).toContain(
660
+ 'new cdktn.AnyMapList(this, "set_map_list_number", true)',
661
+ );
662
+ expect(output).toContain(
663
+ 'new cdktn.AnyMapMap(this, "map_map_map_list_string")',
664
+ );
665
+
666
+ // A supported double nesting (map(list(string))) must still emit its stored class.
667
+ expect(output).toContain('new cdktn.StringListMap(this, "map_list_string")');
668
+
669
+ // map(map(number)) / map(map(bool)) are now directly supported by new core classes.
670
+ expect(output).toContain('new cdktn.NumberMapMap(this, "map_map_number")');
671
+ expect(output).toContain('new cdktn.BooleanMapMap(this, "map_map_bool")');
672
+
673
+ // map(map(string)) is pre-existing, unchanged support.
674
+ expect(output).toContain('new cdktn.StringMapMap(this, "map_map_string")');
675
+
676
+ // Collapsed getters get a JSDoc documenting the Terraform type and the collapse
677
+ // boundary.
678
+ expect(output).toContain("Terraform type: `map(map(list(string)))`");
679
+ expect(output).toContain(
680
+ "it is exposed as `AnyMapMap` and values below that boundary are untyped tokens",
681
+ );
682
+
683
+ // Supported, non-collapsed attributes must NOT get this JSDoc (avoids snapshot churn).
684
+ expect(output).not.toContain("Terraform type: `map(list(string))`");
685
+ expect(output).not.toContain("Terraform type: `map(map(string))`");
686
+ });