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

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,72 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import * as fs from "fs-extra";
4
+ import * as path from "path";
5
+ import { Language, TerraformDependencyConstraint } from "@cdktn/commons";
6
+ import { ConstructsMaker, GetOptions } from "../../constructs-maker";
7
+ import { createTmpHelper } from "../util";
8
+
9
+ const tmp = createTmpHelper();
10
+
11
+ jest.setTimeout(600_000);
12
+ global.setImmediate =
13
+ global.setImmediate ||
14
+ ((fn: any, ...args: any[]) => global.setTimeout(fn, 0, ...args));
15
+
16
+ describe("versions.json file generation", () => {
17
+ const languages = [Language.TYPESCRIPT, Language.PYTHON];
18
+
19
+ const constraints: TerraformDependencyConstraint[] = [
20
+ {
21
+ fqn: "hashicorp/aws",
22
+ name: "aws",
23
+ source: "hashicorp/aws",
24
+ version: "4.0.0",
25
+ },
26
+ {
27
+ fqn: "hashicorp/random",
28
+ name: "random",
29
+ source: "hashicorp/random",
30
+ version: "3.1.3",
31
+ },
32
+ {
33
+ fqn: "kreuzwerker/docker",
34
+ name: "docker",
35
+ source: "kreuzwerker/docker",
36
+ version: "2.16.0",
37
+ },
38
+ ];
39
+
40
+ beforeAll(() => {});
41
+
42
+ test.each(languages)(
43
+ "generates a file for the %s language",
44
+ async (language) => {
45
+ const workdir = tmp("versions-file.test");
46
+
47
+ const options: GetOptions = {
48
+ codeMakerOutput: workdir,
49
+ targetLanguage: language,
50
+ };
51
+
52
+ // Ignore warnings to pop up from the generate function
53
+ process.env.NODE_OPTIONS = "--max-old-space-size=16384";
54
+ const constructMaker = new ConstructsMaker(
55
+ options,
56
+ process.env.CDKTF_EXPERIMENTAL_PROVIDER_SCHEMA_CACHE_PATH,
57
+ );
58
+
59
+ await constructMaker.generate(constraints);
60
+
61
+ const output = fs.readFileSync(
62
+ path.join(workdir, "versions.json"),
63
+ "utf-8",
64
+ );
65
+ expect(Object.keys(JSON.parse(output))).toEqual(
66
+ expect.arrayContaining(
67
+ constraints.map((c) => `registry.terraform.io/${c.fqn}`),
68
+ ),
69
+ );
70
+ },
71
+ );
72
+ });
@@ -0,0 +1,71 @@
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("generate a vault_alicloud_secret_backend resource with a write-only attribute", async () => {
12
+ const code = new CodeMaker();
13
+ const workdir = tmp("write-only.test");
14
+ const spec = JSON.parse(
15
+ fs.readFileSync(
16
+ path.join(__dirname, "fixtures", "write-only.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/vault/alicloud-secret-backend/index.ts"),
25
+ "utf-8",
26
+ );
27
+ expect(output).toMatchSnapshot();
28
+
29
+ // The write-only attribute's getter is deprecated ...
30
+ expect(output).toMatch(
31
+ /@deprecated Write-only: the provider never returns this value[\s\S]*?public get secretKeyWo\(\)/,
32
+ );
33
+ // ... its setter is a plain assignment ...
34
+ expect(output).toMatch(
35
+ /public set secretKeyWo\(value: string\) \{\n\s*this\._secretKeyWo = value;\n\s*\}/,
36
+ );
37
+ // ... and usage registration happens at resolve time, from inside
38
+ // synthesizeAttributes()/synthesizeHclAttributes(), by wrapping the
39
+ // mapped value in markWriteOnlyAttribute() ...
40
+ expect(output).toMatch(
41
+ /secret_key_wo: this\.markWriteOnlyAttribute\(cdktn\.stringToTerraform\(this\._secretKeyWo\)\),/,
42
+ );
43
+ expect(output).toMatch(
44
+ /value: this\.markWriteOnlyAttribute\(cdktn\.stringToHclTerraform\(this\._secretKeyWo\)\),/,
45
+ );
46
+
47
+ // The required write-only attribute gets no reset method (required
48
+ // attributes never do) ...
49
+ expect(output).not.toMatch(/resetSecretKeyWo\b/);
50
+ // ... but the OPTIONAL write-only sibling does, exercising the reset ->
51
+ // clear -> synth-passes path end to end at the generator level.
52
+ expect(output).toMatch(
53
+ /public resetSecondarySecretKeyWo\(\) \{\n\s*this\._secondarySecretKeyWo = undefined;\n\s*\}/,
54
+ );
55
+ expect(output).toMatch(
56
+ /secondary_secret_key_wo: this\.markWriteOnlyAttribute\(cdktn\.stringToTerraform\(this\._secondarySecretKeyWo\)\),/,
57
+ );
58
+
59
+ // The non-write-only sibling attribute is untouched: its getter is
60
+ // emitted directly (no @deprecated JSDoc immediately above), its setter
61
+ // has no registration call, and its synthesis isn't wrapped.
62
+ expect(output).toMatch(
63
+ /private _secretKeyWoVersion\?: number; \n\s*public get secretKeyWoVersion\(\)/,
64
+ );
65
+ expect(output).toMatch(
66
+ /public set secretKeyWoVersion\(value: number\) \{\n\s*this\._secretKeyWoVersion = value;\n\s*\}/,
67
+ );
68
+ expect(output).toMatch(
69
+ /secret_key_wo_version: cdktn\.numberToTerraform\(this\._secretKeyWoVersion\),/,
70
+ );
71
+ });
@@ -0,0 +1,206 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import * as fs from "fs-extra";
4
+ import * as path from "path";
5
+ import {
6
+ Language,
7
+ TerraformDependencyConstraint,
8
+ TerraformTargetVersions,
9
+ } from "@cdktn/commons";
10
+ import { createTmpHelper } from "./util";
11
+
12
+ const mockReadSchema = jest.fn();
13
+ jest.mock("@cdktn/provider-schema", () => ({
14
+ readSchema: (...args: unknown[]) => mockReadSchema(...args),
15
+ }));
16
+
17
+ // Imported after the mock so ConstructsMaker picks up the mocked readSchema.
18
+ import { ConstructsMaker, GetOptions } from "../constructs-maker";
19
+
20
+ const tmp = createTmpHelper();
21
+
22
+ const constraint: TerraformDependencyConstraint = {
23
+ fqn: "hashicorp/random",
24
+ name: "random",
25
+ source: "hashicorp/random",
26
+ version: "3.1.3",
27
+ };
28
+
29
+ // Minimal schema - no resources/data sources - so generation stays within
30
+ // pure TypeScript emission (no jsii-pacmak invocation), mirroring the
31
+ // "empty-provider-resources" fixture used elsewhere in this package.
32
+ const fakeSchema = {
33
+ providerSchema: {
34
+ format_version: "0.2" as const,
35
+ provider_schemas: {
36
+ "registry.terraform.io/hashicorp/random": {
37
+ resource_schemas: null,
38
+ data_source_schemas: null,
39
+ },
40
+ },
41
+ provider_versions: {
42
+ "registry.terraform.io/hashicorp/random": "3.1.3",
43
+ },
44
+ cli_name: "terraform",
45
+ cli_version: "1.7.5",
46
+ },
47
+ };
48
+
49
+ describe("targetVersions threading through 'cdktn get'", () => {
50
+ beforeEach(() => {
51
+ mockReadSchema.mockReset();
52
+ mockReadSchema.mockResolvedValue(fakeSchema);
53
+ });
54
+
55
+ it("passes GetOptions.targetVersions through to readSchema", async () => {
56
+ const workdir = tmp("target-versions-thread.test");
57
+ const targetVersions: TerraformTargetVersions = { terraform: ">=1.5.7" };
58
+ const options: GetOptions = {
59
+ codeMakerOutput: workdir,
60
+ targetLanguage: Language.TYPESCRIPT,
61
+ targetVersions,
62
+ };
63
+
64
+ const maker = new ConstructsMaker(options, "/some/cache/path");
65
+ await maker.generate([constraint]);
66
+
67
+ expect(mockReadSchema).toHaveBeenCalledWith(
68
+ [constraint],
69
+ "/some/cache/path",
70
+ targetVersions,
71
+ );
72
+ });
73
+
74
+ it("omits targetVersions from the readSchema call when not configured", async () => {
75
+ const workdir = tmp("target-versions-absent.test");
76
+ const options: GetOptions = {
77
+ codeMakerOutput: workdir,
78
+ targetLanguage: Language.TYPESCRIPT,
79
+ };
80
+
81
+ const maker = new ConstructsMaker(options);
82
+ await maker.generate([constraint]);
83
+
84
+ expect(mockReadSchema).toHaveBeenCalledWith(
85
+ [constraint],
86
+ undefined,
87
+ undefined,
88
+ );
89
+ });
90
+
91
+ it("stamps constraints.json with targetVersions + cli identity, and older constraints.json files without those fields are still treated as fresh (no forced regeneration)", async () => {
92
+ const workdir = tmp("target-versions-stamp.test");
93
+ const targetVersions: TerraformTargetVersions = { terraform: ">=1.5.7" };
94
+ const options: GetOptions = {
95
+ codeMakerOutput: workdir,
96
+ targetLanguage: Language.TYPESCRIPT,
97
+ targetVersions,
98
+ };
99
+
100
+ const maker = new ConstructsMaker(options);
101
+ await maker.generate([constraint]);
102
+
103
+ const constraintsFile = JSON.parse(
104
+ await fs.readFile(path.join(workdir, "constraints.json"), "utf8"),
105
+ );
106
+ expect(constraintsFile.targetVersions).toEqual(targetVersions);
107
+ expect(constraintsFile.cli).toEqual({
108
+ name: "terraform",
109
+ version: "1.7.5",
110
+ });
111
+
112
+ // Rewrite constraints.json as it would have looked before this feature
113
+ // landed (no targetVersions/cli fields), keeping the rest identical -
114
+ // this simulates re-running `cdktn get` against an output directory
115
+ // generated by an older cdktn version.
116
+ const {
117
+ targetVersions: _tv,
118
+ cli: _cli,
119
+ ...legacyConstraints
120
+ } = constraintsFile;
121
+ await fs.writeFile(
122
+ path.join(workdir, "constraints.json"),
123
+ JSON.stringify(legacyConstraints, null, 2),
124
+ );
125
+
126
+ const maker2 = new ConstructsMaker(options);
127
+ const toGenerate = await maker2.filterAlreadyGenerated([constraint]);
128
+ expect(toGenerate).toEqual([]);
129
+ });
130
+
131
+ it("threads a partial targetVersions (single product) through unchanged and stamps it verbatim", async () => {
132
+ const workdir = tmp("target-versions-partial.test");
133
+ const targetVersions: TerraformTargetVersions = { opentofu: ">=1.11.0" };
134
+ const options: GetOptions = {
135
+ codeMakerOutput: workdir,
136
+ targetLanguage: Language.TYPESCRIPT,
137
+ targetVersions,
138
+ };
139
+
140
+ const maker = new ConstructsMaker(options);
141
+ await maker.generate([constraint]);
142
+
143
+ expect(mockReadSchema).toHaveBeenCalledWith(
144
+ [constraint],
145
+ undefined,
146
+ targetVersions,
147
+ );
148
+
149
+ // The stamp records exactly what the project declared - no terraform
150
+ // default is injected at get-time (defaulting for the undeclared
151
+ // product happens only at synth-time, in resolveTargetVersions).
152
+ const constraintsFile = JSON.parse(
153
+ await fs.readFile(path.join(workdir, "constraints.json"), "utf8"),
154
+ );
155
+ expect(constraintsFile.targetVersions).toEqual({ opentofu: ">=1.11.0" });
156
+ });
157
+
158
+ it("omits the cli stamp when the fetched schema carries no CLI version metadata", async () => {
159
+ const workdir = tmp("target-versions-no-cli.test");
160
+ const {
161
+ cli_name: _cliName,
162
+ cli_version: _cliVersion,
163
+ ...schemaWithoutCli
164
+ } = fakeSchema.providerSchema;
165
+ mockReadSchema.mockResolvedValue({ providerSchema: schemaWithoutCli });
166
+
167
+ const targetVersions: TerraformTargetVersions = { terraform: ">=1.5.7" };
168
+ const options: GetOptions = {
169
+ codeMakerOutput: workdir,
170
+ targetLanguage: Language.TYPESCRIPT,
171
+ targetVersions,
172
+ };
173
+
174
+ const maker = new ConstructsMaker(options);
175
+ await maker.generate([constraint]);
176
+
177
+ const constraintsFile = JSON.parse(
178
+ await fs.readFile(path.join(workdir, "constraints.json"), "utf8"),
179
+ );
180
+ expect(constraintsFile.cli).toBeUndefined();
181
+ expect(constraintsFile.targetVersions).toEqual(targetVersions);
182
+ });
183
+
184
+ it("does not force regeneration when targetVersions change between runs", async () => {
185
+ // The stamp is diagnostic-only: per the GetOptions.targetVersions doc,
186
+ // targetVersions never filters codegen (the full schema surface is
187
+ // always generated), so freshness only compares the providers map and
188
+ // the cdktf version.
189
+ const workdir = tmp("target-versions-change.test");
190
+ const options: GetOptions = {
191
+ codeMakerOutput: workdir,
192
+ targetLanguage: Language.TYPESCRIPT,
193
+ targetVersions: { terraform: ">=1.5.7" },
194
+ };
195
+
196
+ const maker = new ConstructsMaker(options);
197
+ await maker.generate([constraint]);
198
+
199
+ const maker2 = new ConstructsMaker({
200
+ ...options,
201
+ targetVersions: { terraform: ">=1.11.0" },
202
+ });
203
+ const toGenerate = await maker2.filterAlreadyGenerated([constraint]);
204
+ expect(toGenerate).toEqual([]);
205
+ });
206
+ });
@@ -0,0 +1,75 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import * as fs from "fs";
4
+ import * as os from "os";
5
+ import {
6
+ Language,
7
+ TerraformModuleConstraint,
8
+ withTempDir,
9
+ } from "@cdktn/commons";
10
+ import { ConstructsMaker } from "../constructs-maker";
11
+ import * as path from "path";
12
+
13
+ /**
14
+ * Creates a per-test-file temp-dir helper.
15
+ *
16
+ * Returns a `tmp(prefix)` function that creates a uniquely-named directory
17
+ * under `os.tmpdir()` and tracks it. An `afterAll` hook is registered on
18
+ * the calling test file's scope; when the file finishes running, every
19
+ * tracked directory is removed (recursively, force).
20
+ */
21
+ export function createTmpHelper(): (prefix: string) => string {
22
+ const dirs: string[] = [];
23
+ afterAll(() => {
24
+ for (const d of dirs) fs.rmSync(d, { recursive: true, force: true });
25
+ });
26
+ return (prefix: string) => {
27
+ const d = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
28
+ dirs.push(d);
29
+ return d;
30
+ };
31
+ }
32
+
33
+ export function expectModuleToMatchSnapshot(
34
+ testName: string,
35
+ testCategory: string,
36
+ fixtureNames: string[],
37
+ ) {
38
+ test(testName, async () => {
39
+ await withTempDir(`${testName.replace(/\s*/, "-")}.test`, async () => {
40
+ const curdir = process.cwd();
41
+ fs.mkdirSync("module");
42
+
43
+ fixtureNames.forEach((fixtureName) => {
44
+ fs.copyFileSync(
45
+ path.join(__dirname, testCategory, "fixtures", fixtureName),
46
+ path.join(curdir, "module", fixtureName),
47
+ );
48
+ });
49
+
50
+ const constraint = new TerraformModuleConstraint({
51
+ source: "./module",
52
+ name: "module",
53
+ fqn: "module",
54
+ });
55
+
56
+ fs.mkdirSync("work");
57
+ const workdir = path.join(curdir, "work");
58
+
59
+ const maker = new ConstructsMaker(
60
+ {
61
+ codeMakerOutput: workdir,
62
+ targetLanguage: Language.TYPESCRIPT,
63
+ },
64
+ process.env.CDKTF_EXPERIMENTAL_PROVIDER_SCHEMA_CACHE_PATH,
65
+ );
66
+ await maker.generate([constraint]);
67
+
68
+ const output = fs.readFileSync(
69
+ path.join(workdir, "modules/module.ts"),
70
+ "utf-8",
71
+ );
72
+ expect(output).toMatchSnapshot();
73
+ });
74
+ });
75
+ }