@cdktn/provider-generator 0.24.0-pre.7 → 0.24.0-pre.70

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 (71) 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/cli.js +8 -3
  5. package/build/get/__tests__/generator/import-style.test.d.ts +2 -0
  6. package/build/get/__tests__/generator/import-style.test.js +101 -0
  7. package/build/get/__tests__/generator/module-generator.test.js +12 -12
  8. package/build/get/__tests__/generator/provider-source-matching.test.d.ts +2 -0
  9. package/build/get/__tests__/generator/provider-source-matching.test.js +45 -0
  10. package/build/get/constructs-maker.d.ts +5 -1
  11. package/build/get/constructs-maker.js +37 -7
  12. package/build/get/generator/emitter/struct-emitter.d.ts +2 -1
  13. package/build/get/generator/emitter/struct-emitter.js +14 -11
  14. package/build/get/generator/module-generator.js +3 -3
  15. package/build/get/generator/provider-generator.d.ts +9 -1
  16. package/build/get/generator/provider-generator.js +17 -7
  17. package/jest.config.js +16 -9
  18. package/package.json +24 -23
  19. package/package.sh +1 -1
  20. package/src/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +8 -8
  21. package/src/__tests__/__snapshots__/provider.test.ts.snap +2951 -2951
  22. package/src/__tests__/edge-provider-schema/builder.ts +185 -0
  23. package/src/__tests__/edge-provider-schema/cli.ts +51 -0
  24. package/src/__tests__/edge-provider-schema/index.ts +161 -0
  25. package/src/__tests__/edge-provider-schema.test.ts +24 -0
  26. package/src/__tests__/provider.test.ts +180 -0
  27. package/src/get/__tests__/constructs-maker.test.ts +118 -0
  28. package/src/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +5 -5
  29. package/src/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +3310 -3310
  30. package/src/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +355 -355
  31. package/src/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +8 -8
  32. package/src/get/__tests__/generator/__snapshots__/provider.test.ts.snap +8 -8
  33. package/src/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +126 -126
  34. package/src/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +17 -17
  35. package/src/get/__tests__/generator/__snapshots__/types.test.ts.snap +65 -65
  36. package/src/get/__tests__/generator/complex-computed-types.test.ts +28 -0
  37. package/src/get/__tests__/generator/deep-nested-attributes.test.ts +56 -0
  38. package/src/get/__tests__/generator/description-escaping.test.ts +84 -0
  39. package/src/get/__tests__/generator/empty-provider-resources.test.ts +26 -0
  40. package/src/get/__tests__/generator/export-sharding.test.ts +169 -0
  41. package/src/get/__tests__/generator/import-style.test.ts +129 -0
  42. package/src/get/__tests__/generator/module-generator.test.ts +528 -0
  43. package/src/get/__tests__/generator/nested-types.test.ts +54 -0
  44. package/src/get/__tests__/generator/provider-source-matching.test.ts +84 -0
  45. package/src/get/__tests__/generator/provider.test.ts +51 -0
  46. package/src/get/__tests__/generator/resource-types.test.ts +118 -0
  47. package/src/get/__tests__/generator/skipped-attributes.test.ts +72 -0
  48. package/src/get/__tests__/generator/types.test.ts +611 -0
  49. package/src/get/__tests__/generator/versions-file.test.ts +72 -0
  50. package/src/get/__tests__/util.ts +75 -0
  51. package/src/get/constructs-maker.ts +845 -0
  52. package/src/get/generator/custom-defaults.ts +493 -0
  53. package/src/get/generator/emitter/attributes-emitter.ts +225 -0
  54. package/src/get/generator/emitter/index.ts +5 -0
  55. package/src/get/generator/emitter/resource-emitter.ts +226 -0
  56. package/src/get/generator/emitter/struct-emitter.ts +683 -0
  57. package/src/get/generator/loop-detection.ts +81 -0
  58. package/src/get/generator/models/attribute-model.ts +216 -0
  59. package/src/get/generator/models/attribute-type-model.ts +448 -0
  60. package/src/get/generator/models/index.ts +7 -0
  61. package/src/get/generator/models/resource-model.ts +161 -0
  62. package/src/get/generator/models/scope.ts +54 -0
  63. package/src/get/generator/models/struct.ts +116 -0
  64. package/src/get/generator/module-generator.ts +234 -0
  65. package/src/get/generator/provider-generator.ts +362 -0
  66. package/src/get/generator/resource-parser.ts +762 -0
  67. package/src/get/generator/sanitized-comments.ts +49 -0
  68. package/src/get/generator/skipped-attributes.ts +27 -0
  69. package/src/index.ts +40 -0
  70. package/src/util.ts +26 -0
  71. package/tsconfig.json +1 -2
@@ -0,0 +1,528 @@
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 { Language, TerraformModuleConstraint } from "@cdktn/commons";
6
+ import { ConstructsMaker } from "../../constructs-maker";
7
+ import { expectModuleToMatchSnapshot } from "../util";
8
+ import { execSync } from "child_process";
9
+ import { createTmpHelper } from "../util";
10
+
11
+ const tmp = createTmpHelper();
12
+
13
+ const onTf1_6AndNewer = (
14
+ name: string,
15
+ fn: () => Promise<void>,
16
+ timeout?: number,
17
+ ) => {
18
+ const terraformBinaryName = process.env.TERRAFORM_BINARY_NAME || "terraform";
19
+ const output = execSync(`${terraformBinaryName} version -json`);
20
+
21
+ if (!output) {
22
+ throw new Error("Could not determine Terraform version");
23
+ }
24
+
25
+ const tfVersion = JSON.parse(output.toString()).terraform_version;
26
+
27
+ const [major, minor] = tfVersion.toString().split(".");
28
+ if (Number(major) < 1 || (Number(major) === 1 && Number(minor) < 6)) {
29
+ test.skip(
30
+ `${name} (requires Terraform >= 1.6.0; but is ${tfVersion})`,
31
+ fn,
32
+ timeout,
33
+ );
34
+ } else {
35
+ test(name, fn, timeout);
36
+ }
37
+ };
38
+
39
+ test("generate some modules", async () => {
40
+ const workdir = tmp("module-generator.test");
41
+ const constraint = new TerraformModuleConstraint(
42
+ "terraform-aws-modules/eks/aws@7.0.1",
43
+ );
44
+
45
+ const maker = new ConstructsMaker(
46
+ {
47
+ codeMakerOutput: workdir,
48
+ targetLanguage: Language.TYPESCRIPT,
49
+ },
50
+ process.env.CDKTF_EXPERIMENTAL_PROVIDER_SCHEMA_CACHE_PATH,
51
+ );
52
+ await maker.generate([constraint]);
53
+
54
+ const output = fs.readFileSync(
55
+ path.join(workdir, "modules/terraform-aws-modules/aws/eks.ts"),
56
+ "utf-8",
57
+ );
58
+ expect(output).toMatchSnapshot();
59
+ }, 120000);
60
+
61
+ expectModuleToMatchSnapshot("no module outputs", "generator", [
62
+ "module-no-outputs.test.fixture.tf",
63
+ ]);
64
+
65
+ expectModuleToMatchSnapshot("typeless variables", "generator", [
66
+ "module-no-variable-type.test.fixture.tf",
67
+ ]);
68
+
69
+ expectModuleToMatchSnapshot("no newline", "generator", [
70
+ "module-no-newline-1.test.fixture.tf",
71
+ "module-no-newline-2.test.fixture.tf",
72
+ ]);
73
+
74
+ test("generate multiple aws modules", async () => {
75
+ jest.setTimeout(120000);
76
+
77
+ const workdir = tmp("module-generator-aws.test");
78
+ const constraints = [
79
+ new TerraformModuleConstraint("terraform-aws-modules/vpc/aws@2.78.0"),
80
+ new TerraformModuleConstraint("terraform-aws-modules/rds-aurora/aws@4.1.0"),
81
+ ];
82
+
83
+ const maker = new ConstructsMaker(
84
+ {
85
+ codeMakerOutput: workdir,
86
+ targetLanguage: Language.TYPESCRIPT,
87
+ },
88
+ process.env.CDKTF_EXPERIMENTAL_PROVIDER_SCHEMA_CACHE_PATH,
89
+ );
90
+ await maker.generate(constraints);
91
+
92
+ const vpcOutput = fs.readFileSync(
93
+ path.join(workdir, "modules/terraform-aws-modules/aws/vpc.ts"),
94
+ "utf-8",
95
+ );
96
+ expect(vpcOutput).toMatchSnapshot();
97
+
98
+ const rdsOutput = fs.readFileSync(
99
+ path.join(workdir, "modules/terraform-aws-modules/aws/rds-aurora.ts"),
100
+ "utf-8",
101
+ );
102
+ expect(rdsOutput).toMatchSnapshot();
103
+ }, 120000);
104
+
105
+ test("generate nested module", async () => {
106
+ const workdir = tmp("module-generator-nested.test");
107
+ const constraint = new TerraformModuleConstraint(
108
+ "terraform-aws-modules/vpc/aws//modules/vpc-endpoints@3.19.0",
109
+ );
110
+
111
+ const maker = new ConstructsMaker(
112
+ {
113
+ codeMakerOutput: workdir,
114
+ targetLanguage: Language.TYPESCRIPT,
115
+ },
116
+ process.env.CDKTF_EXPERIMENTAL_PROVIDER_SCHEMA_CACHE_PATH,
117
+ );
118
+ await maker.generate([constraint]);
119
+
120
+ const output = fs.readFileSync(
121
+ path.join(
122
+ workdir,
123
+ "modules/terraform-aws-modules/aws/vpc/modules/vpc-endpoints.ts",
124
+ ),
125
+ "utf-8",
126
+ );
127
+ expect(output).toMatchSnapshot();
128
+ }, 120000);
129
+
130
+ expectModuleToMatchSnapshot("getX variables", "generator", [
131
+ "module-get-x.test.fixture.tf",
132
+ ]);
133
+
134
+ expectModuleToMatchSnapshot(
135
+ "handle */* in module variable default string",
136
+ "generator",
137
+ ["module-with-star-default.test.fixture.tf"],
138
+ );
139
+
140
+ onTf1_6AndNewer(
141
+ "generate module that can't be initialized",
142
+ async () => {
143
+ jest.setTimeout(120000);
144
+
145
+ const workdir = tmp("module-generator.test-no-init");
146
+ const constraint = new TerraformModuleConstraint(
147
+ "milliHQ/next-js/aws@1.0.0-canary.5",
148
+ );
149
+
150
+ const maker = new ConstructsMaker(
151
+ {
152
+ codeMakerOutput: workdir,
153
+ targetLanguage: Language.TYPESCRIPT,
154
+ },
155
+ process.env.CDKTF_EXPERIMENTAL_PROVIDER_SCHEMA_CACHE_PATH,
156
+ );
157
+ await maker.generate([constraint]);
158
+
159
+ const output = fs.readFileSync(
160
+ path.join(workdir, "modules/milliHQ/aws/next-js.ts"),
161
+ "utf-8",
162
+ );
163
+
164
+ // yes, this is a lot of code, but this test is skipped for some Terraform versions
165
+ // which then shows snapshots as obsolete which fails the test
166
+ // this way, there's no such problem if the test is skipped
167
+ expect(output).toMatchInlineSnapshot(`
168
+ "// generated by cdktn get
169
+ // milliHQ/next-js/aws
170
+ import { TerraformModule, type TerraformModuleUserConfig } from 'cdktn';
171
+ import { Construct } from 'constructs';
172
+ export interface NextJsConfig extends TerraformModuleUserConfig {
173
+ /**
174
+ * ACM certificate arn for custom_domain
175
+ */
176
+ readonly cloudfrontAcmCertificateArn?: string;
177
+ /**
178
+ * Aliases for custom_domain
179
+ *
180
+ */
181
+ readonly cloudfrontAliases?: string[];
182
+ /**
183
+ * Header keys that should be used to calculate the cache key in CloudFront.
184
+ * Authorization
185
+ */
186
+ readonly cloudfrontCacheKeyHeaders?: string[];
187
+ /**
188
+ * Controls whether the main CloudFront distribution should be created.
189
+ * true
190
+ */
191
+ readonly cloudfrontCreateDistribution?: boolean;
192
+ /**
193
+ * When using an external CloudFront distribution provide its arn.
194
+ */
195
+ readonly cloudfrontExternalArn?: string;
196
+ /**
197
+ * When using an external CloudFront distribution provide its id.
198
+ */
199
+ readonly cloudfrontExternalId?: string;
200
+ /**
201
+ * The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. One of SSLv3, TLSv1, TLSv1_2016, TLSv1.1_2016, TLSv1.2_2018 or TLSv1.2_2019.
202
+ * TLSv1
203
+ */
204
+ readonly cloudfrontMinimumProtocolVersion?: string;
205
+ /**
206
+ * Id of a custom request policy that overrides the default policy (AllViewer). Can be custom or managed.
207
+ */
208
+ readonly cloudfrontOriginRequestPolicy?: string;
209
+ /**
210
+ * Price class for the CloudFront distributions (main & proxy config). One of PriceClass_All, PriceClass_200, PriceClass_100.
211
+ * PriceClass_100
212
+ */
213
+ readonly cloudfrontPriceClass?: string;
214
+ /**
215
+ * Id of a response headers policy. Can be custom or managed. Default is empty.
216
+ */
217
+ readonly cloudfrontResponseHeadersPolicy?: string;
218
+ /**
219
+ * An optional webacl2 arn or webacl id to associate with the cloudfront distribution
220
+ */
221
+ readonly cloudfrontWebaclId?: string;
222
+ /**
223
+ * Controls whether resources for image optimization support should be created or not.
224
+ * true
225
+ */
226
+ readonly createImageOptimization?: boolean;
227
+ /**
228
+ * Use locally built packages rather than download them from npm.
229
+ */
230
+ readonly debugUseLocalPackages?: boolean;
231
+ /**
232
+ * Identifier for the deployment group (only lowercase alphanumeric characters and hyphens are allowed).
233
+ * tf-next
234
+ */
235
+ readonly deploymentName?: string;
236
+ /**
237
+ * Controls whether it should be possible to run multiple deployments in parallel (requires multiple_deployments_base_domain).
238
+ */
239
+ readonly enableMultipleDeployments?: boolean;
240
+ /**
241
+ * Amount of memory in MB the worker Lambda Function for image optimization can use. Valid value between 128 MB to 10,240 MB, in 1 MB increments.
242
+ * 2,048
243
+ */
244
+ readonly imageOptimizationLambdaMemorySize?: number;
245
+ /**
246
+ * Whether to deploy additional lambda JSON policies. If false, lambda_policy_json will not be attached to the lambda function. (Necessary since policy strings are only known after apply when using Terraforms data.aws_iam_policy_document)
247
+ */
248
+ readonly lambdaAttachPolicyJson?: boolean;
249
+ /**
250
+ * Set to true if the Lambda functions should be attached to a VPC. Use this setting if VPC resources should be accessed by the Lambda functions. When setting this to true, use vpc_security_group_ids and vpc_subnet_ids to specify the VPC networking. Note that attaching to a VPC would introduce a delay on to cold starts
251
+ */
252
+ readonly lambdaAttachToVpc?: boolean;
253
+ /**
254
+ * Additional policy document as JSON to attach to the Lambda Function role
255
+ */
256
+ readonly lambdaPolicyJson?: string;
257
+ /**
258
+ * ARN of IAM policy that scopes aws_iam_role access for the lambda
259
+ */
260
+ readonly lambdaRolePermissionsBoundary?: string;
261
+ /**
262
+ * Default wildcard domain where new deployments should be available. Should be in the form of *.example.com.
263
+ */
264
+ readonly multipleDeploymentsBaseDomain?: string;
265
+ /**
266
+ * Tag metadata to label AWS resources that support tags.
267
+ * The property type contains a map, they have special handling, please see {@link cdk.tf/module-map-inputs the docs}
268
+ */
269
+ readonly tags?: { [key: string]: string };
270
+ /**
271
+ * Tag metadata to label AWS S3 buckets. Overrides tags with the same name in input variable tags.
272
+ * The property type contains a map, they have special handling, please see {@link cdk.tf/module-map-inputs the docs}
273
+ */
274
+ readonly tagsS3Bucket?: { [key: string]: string };
275
+ /**
276
+ * The list of Security Group IDs to be used by the Lambda functions. lambda_attach_to_vpc should be set to true for these to be applied.
277
+ *
278
+ */
279
+ readonly vpcSecurityGroupIds?: string[];
280
+ /**
281
+ * The list of VPC subnet IDs to attach the Lambda functions. lambda_attach_to_vpc should be set to true for these to be applied.
282
+ *
283
+ */
284
+ readonly vpcSubnetIds?: string[];
285
+ }
286
+ /**
287
+ * Defines an NextJs based on a Terraform module
288
+ *
289
+ * Docs at Terraform Registry: {@link https://registry.terraform.io/modules/milliHQ/next-js/aws/1.0.0-canary.5 milliHQ/next-js/aws}
290
+ */
291
+ export class NextJs extends TerraformModule {
292
+ private readonly inputs: { [name: string]: any } = { };
293
+ public constructor(scope: Construct, id: string, config: NextJsConfig = {}) {
294
+ super(scope, id, {
295
+ ...config,
296
+ source: 'milliHQ/next-js/aws',
297
+ version: '1.0.0-canary.5',
298
+ });
299
+ this.cloudfrontAcmCertificateArn = config.cloudfrontAcmCertificateArn;
300
+ this.cloudfrontAliases = config.cloudfrontAliases;
301
+ this.cloudfrontCacheKeyHeaders = config.cloudfrontCacheKeyHeaders;
302
+ this.cloudfrontCreateDistribution = config.cloudfrontCreateDistribution;
303
+ this.cloudfrontExternalArn = config.cloudfrontExternalArn;
304
+ this.cloudfrontExternalId = config.cloudfrontExternalId;
305
+ this.cloudfrontMinimumProtocolVersion = config.cloudfrontMinimumProtocolVersion;
306
+ this.cloudfrontOriginRequestPolicy = config.cloudfrontOriginRequestPolicy;
307
+ this.cloudfrontPriceClass = config.cloudfrontPriceClass;
308
+ this.cloudfrontResponseHeadersPolicy = config.cloudfrontResponseHeadersPolicy;
309
+ this.cloudfrontWebaclId = config.cloudfrontWebaclId;
310
+ this.createImageOptimization = config.createImageOptimization;
311
+ this.debugUseLocalPackages = config.debugUseLocalPackages;
312
+ this.deploymentName = config.deploymentName;
313
+ this.enableMultipleDeployments = config.enableMultipleDeployments;
314
+ this.imageOptimizationLambdaMemorySize = config.imageOptimizationLambdaMemorySize;
315
+ this.lambdaAttachPolicyJson = config.lambdaAttachPolicyJson;
316
+ this.lambdaAttachToVpc = config.lambdaAttachToVpc;
317
+ this.lambdaPolicyJson = config.lambdaPolicyJson;
318
+ this.lambdaRolePermissionsBoundary = config.lambdaRolePermissionsBoundary;
319
+ this.multipleDeploymentsBaseDomain = config.multipleDeploymentsBaseDomain;
320
+ this.tags = config.tags;
321
+ this.tagsS3Bucket = config.tagsS3Bucket;
322
+ this.vpcSecurityGroupIds = config.vpcSecurityGroupIds;
323
+ this.vpcSubnetIds = config.vpcSubnetIds;
324
+ }
325
+ public get cloudfrontAcmCertificateArn(): string | undefined {
326
+ return this.inputs['cloudfront_acm_certificate_arn'] as string | undefined;
327
+ }
328
+ public set cloudfrontAcmCertificateArn(value: string | undefined) {
329
+ this.inputs['cloudfront_acm_certificate_arn'] = value;
330
+ }
331
+ public get cloudfrontAliases(): string[] | undefined {
332
+ return this.inputs['cloudfront_aliases'] as string[] | undefined;
333
+ }
334
+ public set cloudfrontAliases(value: string[] | undefined) {
335
+ this.inputs['cloudfront_aliases'] = value;
336
+ }
337
+ public get cloudfrontCacheKeyHeaders(): string[] | undefined {
338
+ return this.inputs['cloudfront_cache_key_headers'] as string[] | undefined;
339
+ }
340
+ public set cloudfrontCacheKeyHeaders(value: string[] | undefined) {
341
+ this.inputs['cloudfront_cache_key_headers'] = value;
342
+ }
343
+ public get cloudfrontCreateDistribution(): boolean | undefined {
344
+ return this.inputs['cloudfront_create_distribution'] as boolean | undefined;
345
+ }
346
+ public set cloudfrontCreateDistribution(value: boolean | undefined) {
347
+ this.inputs['cloudfront_create_distribution'] = value;
348
+ }
349
+ public get cloudfrontExternalArn(): string | undefined {
350
+ return this.inputs['cloudfront_external_arn'] as string | undefined;
351
+ }
352
+ public set cloudfrontExternalArn(value: string | undefined) {
353
+ this.inputs['cloudfront_external_arn'] = value;
354
+ }
355
+ public get cloudfrontExternalId(): string | undefined {
356
+ return this.inputs['cloudfront_external_id'] as string | undefined;
357
+ }
358
+ public set cloudfrontExternalId(value: string | undefined) {
359
+ this.inputs['cloudfront_external_id'] = value;
360
+ }
361
+ public get cloudfrontMinimumProtocolVersion(): string | undefined {
362
+ return this.inputs['cloudfront_minimum_protocol_version'] as string | undefined;
363
+ }
364
+ public set cloudfrontMinimumProtocolVersion(value: string | undefined) {
365
+ this.inputs['cloudfront_minimum_protocol_version'] = value;
366
+ }
367
+ public get cloudfrontOriginRequestPolicy(): string | undefined {
368
+ return this.inputs['cloudfront_origin_request_policy'] as string | undefined;
369
+ }
370
+ public set cloudfrontOriginRequestPolicy(value: string | undefined) {
371
+ this.inputs['cloudfront_origin_request_policy'] = value;
372
+ }
373
+ public get cloudfrontPriceClass(): string | undefined {
374
+ return this.inputs['cloudfront_price_class'] as string | undefined;
375
+ }
376
+ public set cloudfrontPriceClass(value: string | undefined) {
377
+ this.inputs['cloudfront_price_class'] = value;
378
+ }
379
+ public get cloudfrontResponseHeadersPolicy(): string | undefined {
380
+ return this.inputs['cloudfront_response_headers_policy'] as string | undefined;
381
+ }
382
+ public set cloudfrontResponseHeadersPolicy(value: string | undefined) {
383
+ this.inputs['cloudfront_response_headers_policy'] = value;
384
+ }
385
+ public get cloudfrontWebaclId(): string | undefined {
386
+ return this.inputs['cloudfront_webacl_id'] as string | undefined;
387
+ }
388
+ public set cloudfrontWebaclId(value: string | undefined) {
389
+ this.inputs['cloudfront_webacl_id'] = value;
390
+ }
391
+ public get createImageOptimization(): boolean | undefined {
392
+ return this.inputs['create_image_optimization'] as boolean | undefined;
393
+ }
394
+ public set createImageOptimization(value: boolean | undefined) {
395
+ this.inputs['create_image_optimization'] = value;
396
+ }
397
+ public get debugUseLocalPackages(): boolean | undefined {
398
+ return this.inputs['debug_use_local_packages'] as boolean | undefined;
399
+ }
400
+ public set debugUseLocalPackages(value: boolean | undefined) {
401
+ this.inputs['debug_use_local_packages'] = value;
402
+ }
403
+ public get deploymentName(): string | undefined {
404
+ return this.inputs['deployment_name'] as string | undefined;
405
+ }
406
+ public set deploymentName(value: string | undefined) {
407
+ this.inputs['deployment_name'] = value;
408
+ }
409
+ public get enableMultipleDeployments(): boolean | undefined {
410
+ return this.inputs['enable_multiple_deployments'] as boolean | undefined;
411
+ }
412
+ public set enableMultipleDeployments(value: boolean | undefined) {
413
+ this.inputs['enable_multiple_deployments'] = value;
414
+ }
415
+ public get imageOptimizationLambdaMemorySize(): number | undefined {
416
+ return this.inputs['image_optimization_lambda_memory_size'] as number | undefined;
417
+ }
418
+ public set imageOptimizationLambdaMemorySize(value: number | undefined) {
419
+ this.inputs['image_optimization_lambda_memory_size'] = value;
420
+ }
421
+ public get lambdaAttachPolicyJson(): boolean | undefined {
422
+ return this.inputs['lambda_attach_policy_json'] as boolean | undefined;
423
+ }
424
+ public set lambdaAttachPolicyJson(value: boolean | undefined) {
425
+ this.inputs['lambda_attach_policy_json'] = value;
426
+ }
427
+ public get lambdaAttachToVpc(): boolean | undefined {
428
+ return this.inputs['lambda_attach_to_vpc'] as boolean | undefined;
429
+ }
430
+ public set lambdaAttachToVpc(value: boolean | undefined) {
431
+ this.inputs['lambda_attach_to_vpc'] = value;
432
+ }
433
+ public get lambdaPolicyJson(): string | undefined {
434
+ return this.inputs['lambda_policy_json'] as string | undefined;
435
+ }
436
+ public set lambdaPolicyJson(value: string | undefined) {
437
+ this.inputs['lambda_policy_json'] = value;
438
+ }
439
+ public get lambdaRolePermissionsBoundary(): string | undefined {
440
+ return this.inputs['lambda_role_permissions_boundary'] as string | undefined;
441
+ }
442
+ public set lambdaRolePermissionsBoundary(value: string | undefined) {
443
+ this.inputs['lambda_role_permissions_boundary'] = value;
444
+ }
445
+ public get multipleDeploymentsBaseDomain(): string | undefined {
446
+ return this.inputs['multiple_deployments_base_domain'] as string | undefined;
447
+ }
448
+ public set multipleDeploymentsBaseDomain(value: string | undefined) {
449
+ this.inputs['multiple_deployments_base_domain'] = value;
450
+ }
451
+ public get tags(): { [key: string]: string } | undefined {
452
+ return this.inputs['tags'] as { [key: string]: string } | undefined;
453
+ }
454
+ public set tags(value: { [key: string]: string } | undefined) {
455
+ this.inputs['tags'] = value;
456
+ }
457
+ public get tagsS3Bucket(): { [key: string]: string } | undefined {
458
+ return this.inputs['tags_s3_bucket'] as { [key: string]: string } | undefined;
459
+ }
460
+ public set tagsS3Bucket(value: { [key: string]: string } | undefined) {
461
+ this.inputs['tags_s3_bucket'] = value;
462
+ }
463
+ public get vpcSecurityGroupIds(): string[] | undefined {
464
+ return this.inputs['vpc_security_group_ids'] as string[] | undefined;
465
+ }
466
+ public set vpcSecurityGroupIds(value: string[] | undefined) {
467
+ this.inputs['vpc_security_group_ids'] = value;
468
+ }
469
+ public get vpcSubnetIds(): string[] | undefined {
470
+ return this.inputs['vpc_subnet_ids'] as string[] | undefined;
471
+ }
472
+ public set vpcSubnetIds(value: string[] | undefined) {
473
+ this.inputs['vpc_subnet_ids'] = value;
474
+ }
475
+ public get apiEndpointOutput() {
476
+ return this.getString('api_endpoint');
477
+ }
478
+ public get apiEndpointAccessPolicyArnOutput() {
479
+ return this.getString('api_endpoint_access_policy_arn');
480
+ }
481
+ public get cloudfrontCustomErrorResponseOutput() {
482
+ return this.getString('cloudfront_custom_error_response');
483
+ }
484
+ public get cloudfrontDefaultCacheBehaviorOutput() {
485
+ return this.getString('cloudfront_default_cache_behavior');
486
+ }
487
+ public get cloudfrontDefaultRootObjectOutput() {
488
+ return this.getString('cloudfront_default_root_object');
489
+ }
490
+ public get cloudfrontDomainNameOutput() {
491
+ return this.getString('cloudfront_domain_name');
492
+ }
493
+ public get cloudfrontHostedZoneIdOutput() {
494
+ return this.getString('cloudfront_hosted_zone_id');
495
+ }
496
+ public get cloudfrontOrderedCacheBehaviorsOutput() {
497
+ return this.getString('cloudfront_ordered_cache_behaviors');
498
+ }
499
+ public get cloudfrontOriginsOutput() {
500
+ return this.getString('cloudfront_origins');
501
+ }
502
+ public get uploadBucketIdOutput() {
503
+ return this.getString('upload_bucket_id');
504
+ }
505
+ protected synthesizeAttributes() {
506
+ return this.inputs;
507
+ }
508
+ protected synthesizeHclAttributes(): { [name: string]: any } {
509
+ return Object.fromEntries(
510
+ Object.entries(this.inputs)
511
+ .filter(([, val]) => val !== undefined)
512
+ .map(([key, val]) => {
513
+ return [
514
+ key,
515
+ {
516
+ value: val,
517
+ type: "any",
518
+ },
519
+ ];
520
+ })
521
+ );
522
+ }
523
+ }
524
+ "
525
+ `);
526
+ },
527
+ 120000,
528
+ );
@@ -0,0 +1,54 @@
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 { CodeMaker } from "codemaker";
6
+ import { TerraformProviderGenerator } from "../../generator/provider-generator";
7
+ import { createTmpHelper } from "../util";
8
+
9
+ const tmp = createTmpHelper();
10
+
11
+ test("generate a resource with nested types", async () => {
12
+ const code = new CodeMaker();
13
+ const workdir = tmp("nested-types.test");
14
+ const spec = JSON.parse(
15
+ fs.readFileSync(
16
+ path.join(__dirname, "fixtures", "nested-types.test.fixture.json"),
17
+ "utf-8",
18
+ ),
19
+ );
20
+ new TerraformProviderGenerator(code, spec).generateAll();
21
+ await code.save(workdir);
22
+
23
+ const output = fs.readFileSync(
24
+ path.join(workdir, "providers/test/nested-types-resource/index.ts"),
25
+ "utf-8",
26
+ );
27
+ expect(output).toMatchSnapshot();
28
+ });
29
+
30
+ test("generate a resource with nested type and no attributes", async () => {
31
+ const code = new CodeMaker();
32
+ const workdir = tmp("nested-type-without-attributes.test");
33
+ const spec = JSON.parse(
34
+ fs.readFileSync(
35
+ path.join(
36
+ __dirname,
37
+ "fixtures",
38
+ "nested-type-without-attributes.test.fixture.json",
39
+ ),
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(
48
+ workdir,
49
+ "providers/test/nested-type-without-attributes-resource/index.ts",
50
+ ),
51
+ "utf-8",
52
+ );
53
+ expect(output).toMatchSnapshot();
54
+ });
@@ -0,0 +1,84 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import {
4
+ ConstructsMakerProviderTarget,
5
+ Language,
6
+ ProviderSchema,
7
+ TerraformProviderConstraint,
8
+ } from "@cdktn/commons";
9
+ import { CodeMaker } from "codemaker";
10
+ import { TerraformProviderGenerator } from "../../generator/provider-generator";
11
+
12
+ // Builds a minimal provider schema keyed by a single FQPN. The provider body is
13
+ // intentionally empty (like the empty-provider-resources fixture) since these
14
+ // tests only exercise the schema-key <-> target-source matching logic.
15
+ const schemaWithKey = (fqpn: string): ProviderSchema => ({
16
+ provider_schemas: {
17
+ [fqpn]: { resource_schemas: null } as any,
18
+ },
19
+ provider_versions: {
20
+ [fqpn]: "1.84.0",
21
+ },
22
+ });
23
+
24
+ const targetForSource = (source: string) =>
25
+ new ConstructsMakerProviderTarget(
26
+ new TerraformProviderConstraint(`${source}@1.84.0`),
27
+ Language.TYPESCRIPT,
28
+ );
29
+
30
+ const generateFor = (schemaKey: string, source: string) => {
31
+ const generator = new TerraformProviderGenerator(
32
+ new CodeMaker(),
33
+ schemaWithKey(schemaKey),
34
+ );
35
+ generator.generate(targetForSource(source));
36
+ return generator;
37
+ };
38
+
39
+ describe("provider source matching against schema keys", () => {
40
+ it("matches a shorthand source against an OpenTofu registry schema key", () => {
41
+ // Regression test for #216: `tofu providers schema` returns keys under
42
+ // registry.opentofu.org, so a shorthand source must not assume
43
+ // registry.terraform.io.
44
+ const generator = generateFor(
45
+ "registry.opentofu.org/hashicorp/awscc",
46
+ "hashicorp/awscc",
47
+ );
48
+
49
+ expect(Object.keys(generator.versions)).toContain(
50
+ "registry.opentofu.org/hashicorp/awscc",
51
+ );
52
+ });
53
+
54
+ it("matches a shorthand source against a Terraform registry schema key", () => {
55
+ const generator = generateFor(
56
+ "registry.terraform.io/hashicorp/awscc",
57
+ "hashicorp/awscc",
58
+ );
59
+
60
+ expect(Object.keys(generator.versions)).toContain(
61
+ "registry.terraform.io/hashicorp/awscc",
62
+ );
63
+ });
64
+
65
+ it("keeps an explicit hostname strict and does not cross registries", () => {
66
+ expect(() =>
67
+ generateFor(
68
+ "registry.opentofu.org/hashicorp/awscc",
69
+ "registry.terraform.io/hashicorp/awscc",
70
+ ),
71
+ ).toThrow(/Could not find provider with constraint/);
72
+ });
73
+
74
+ it("matches an explicit hostname when it agrees with the schema key", () => {
75
+ const generator = generateFor(
76
+ "registry.opentofu.org/hashicorp/awscc",
77
+ "registry.opentofu.org/hashicorp/awscc",
78
+ );
79
+
80
+ expect(Object.keys(generator.versions)).toContain(
81
+ "registry.opentofu.org/hashicorp/awscc",
82
+ );
83
+ });
84
+ });