@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.
- package/.spec.swcrc +22 -0
- package/LICENSE +355 -0
- package/README.md +1 -1
- package/build/__tests__/edge-provider-schema/builder.d.ts +9 -3
- package/build/__tests__/edge-provider-schema/builder.js +6 -3
- package/build/__tests__/edge-provider-schema/cli.js +8 -3
- package/build/__tests__/edge-provider-schema/index.js +119 -1
- package/build/__tests__/provider.test.js +4 -1
- package/build/get/__tests__/generator/ephemeral-resources.test.d.ts +2 -0
- package/build/get/__tests__/generator/ephemeral-resources.test.js +49 -0
- package/build/get/__tests__/generator/module-generator.test.js +12 -12
- package/build/get/__tests__/generator/provider-functions.test.d.ts +2 -0
- package/build/get/__tests__/generator/provider-functions.test.js +176 -0
- package/build/get/__tests__/generator/provider-source-matching.test.d.ts +2 -0
- package/build/get/__tests__/generator/provider-source-matching.test.js +45 -0
- package/build/get/__tests__/generator/provider.test.js +9 -1
- package/build/get/__tests__/generator/supported-stored-classes.test.d.ts +2 -0
- package/build/get/__tests__/generator/supported-stored-classes.test.js +137 -0
- package/build/get/__tests__/generator/types.test.js +44 -1
- package/build/get/__tests__/generator/write-only.test.d.ts +2 -0
- package/build/get/__tests__/generator/write-only.test.js +65 -0
- package/build/get/__tests__/target-versions.test.d.ts +2 -0
- package/build/get/__tests__/target-versions.test.js +171 -0
- package/build/get/constructs-maker.d.ts +8 -1
- package/build/get/constructs-maker.js +46 -10
- package/build/get/generator/emitter/attributes-emitter.d.ts +13 -2
- package/build/get/generator/emitter/attributes-emitter.js +71 -5
- package/build/get/generator/emitter/index.d.ts +1 -0
- package/build/get/generator/emitter/index.js +2 -1
- package/build/get/generator/emitter/provider-functions-emitter.d.ts +11 -0
- package/build/get/generator/emitter/provider-functions-emitter.js +94 -0
- package/build/get/generator/emitter/resource-emitter.d.ts +5 -1
- package/build/get/generator/emitter/resource-emitter.js +83 -7
- package/build/get/generator/emitter/struct-emitter.js +10 -10
- package/build/get/generator/models/attribute-model.d.ts +4 -0
- package/build/get/generator/models/attribute-model.js +50 -4
- package/build/get/generator/models/attribute-type-model.d.ts +24 -0
- package/build/get/generator/models/attribute-type-model.js +91 -5
- package/build/get/generator/models/index.d.ts +1 -0
- package/build/get/generator/models/index.js +2 -1
- package/build/get/generator/models/provider-function-model.d.ts +102 -0
- package/build/get/generator/models/provider-function-model.js +667 -0
- package/build/get/generator/models/resource-model.d.ts +3 -0
- package/build/get/generator/models/resource-model.js +13 -4
- package/build/get/generator/models/struct.d.ts +2 -0
- package/build/get/generator/models/struct.js +6 -2
- package/build/get/generator/models/supported-stored-classes.d.ts +5 -0
- package/build/get/generator/models/supported-stored-classes.js +86 -0
- package/build/get/generator/module-generator.js +3 -3
- package/build/get/generator/provider-generator.d.ts +2 -0
- package/build/get/generator/provider-generator.js +41 -6
- package/build/get/generator/resource-parser.js +3 -1
- package/jest.config.js +16 -9
- package/package.json +28 -27
- package/package.sh +1 -1
- package/src/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +4 -0
- package/src/__tests__/__snapshots__/provider.test.ts.snap +2828 -2828
- package/src/__tests__/edge-provider-schema/builder.ts +201 -0
- package/src/__tests__/edge-provider-schema/cli.ts +51 -0
- package/src/__tests__/edge-provider-schema/index.ts +284 -0
- package/src/__tests__/edge-provider-schema.test.ts +24 -0
- package/src/__tests__/provider.test.ts +183 -0
- package/src/get/__tests__/constructs-maker.test.ts +118 -0
- package/src/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +5 -5
- package/src/get/__tests__/generator/__snapshots__/ephemeral-resources.test.ts.snap +524 -0
- package/src/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +3310 -3310
- package/src/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +355 -355
- package/src/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +8 -8
- package/src/get/__tests__/generator/__snapshots__/provider-functions.test.ts.snap +444 -0
- package/src/get/__tests__/generator/__snapshots__/provider.test.ts.snap +8 -8
- package/src/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +126 -126
- package/src/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +17 -17
- package/src/get/__tests__/generator/__snapshots__/types.test.ts.snap +201 -52
- package/src/get/__tests__/generator/__snapshots__/write-only.test.ts.snap +262 -0
- package/src/get/__tests__/generator/complex-computed-types.test.ts +28 -0
- package/src/get/__tests__/generator/deep-nested-attributes.test.ts +56 -0
- package/src/get/__tests__/generator/description-escaping.test.ts +84 -0
- package/src/get/__tests__/generator/empty-provider-resources.test.ts +26 -0
- package/src/get/__tests__/generator/ephemeral-resources.test.ts +46 -0
- package/src/get/__tests__/generator/export-sharding.test.ts +169 -0
- package/src/get/__tests__/generator/fixtures/deeply-nested-collections.test.fixture.json +129 -0
- package/src/get/__tests__/generator/fixtures/ephemeral-resources.test.fixture.json +160 -0
- package/src/get/__tests__/generator/fixtures/provider-functions-collision.test.fixture.json +31 -0
- package/src/get/__tests__/generator/fixtures/provider-functions-synthetic.test.fixture.json +192 -0
- package/src/get/__tests__/generator/fixtures/provider-functions.test.fixture.json +170 -0
- package/src/get/__tests__/generator/fixtures/write-only.test.fixture.json +58 -0
- package/src/get/__tests__/generator/import-style.test.ts +129 -0
- package/src/get/__tests__/generator/module-generator.test.ts +528 -0
- package/src/get/__tests__/generator/nested-types.test.ts +54 -0
- package/src/get/__tests__/generator/provider-functions.test.ts +262 -0
- package/src/get/__tests__/generator/provider-source-matching.test.ts +84 -0
- package/src/get/__tests__/generator/provider.test.ts +59 -0
- package/src/get/__tests__/generator/resource-types.test.ts +118 -0
- package/src/get/__tests__/generator/skipped-attributes.test.ts +72 -0
- package/src/get/__tests__/generator/supported-stored-classes.test.ts +147 -0
- package/src/get/__tests__/generator/types.test.ts +686 -0
- package/src/get/__tests__/generator/versions-file.test.ts +72 -0
- package/src/get/__tests__/generator/write-only.test.ts +71 -0
- package/src/get/__tests__/target-versions.test.ts +206 -0
- package/src/get/__tests__/util.ts +75 -0
- package/src/get/constructs-maker.ts +885 -0
- package/src/get/generator/custom-defaults.ts +493 -0
- package/src/get/generator/emitter/attributes-emitter.ts +316 -0
- package/src/get/generator/emitter/index.ts +6 -0
- package/src/get/generator/emitter/provider-functions-emitter.ts +117 -0
- package/src/get/generator/emitter/resource-emitter.ts +330 -0
- package/src/get/generator/emitter/struct-emitter.ts +683 -0
- package/src/get/generator/loop-detection.ts +81 -0
- package/src/get/generator/models/attribute-model.ts +273 -0
- package/src/get/generator/models/attribute-type-model.ts +560 -0
- package/src/get/generator/models/index.ts +8 -0
- package/src/get/generator/models/provider-function-model.ts +872 -0
- package/src/get/generator/models/resource-model.ts +183 -0
- package/src/get/generator/models/scope.ts +54 -0
- package/src/get/generator/models/struct.ts +124 -0
- package/src/get/generator/models/supported-stored-classes.ts +88 -0
- package/src/get/generator/module-generator.ts +234 -0
- package/src/get/generator/provider-generator.ts +428 -0
- package/src/get/generator/resource-parser.ts +764 -0
- package/src/get/generator/sanitized-comments.ts +49 -0
- package/src/get/generator/skipped-attributes.ts +27 -0
- package/src/index.ts +40 -0
- package/src/util.ts +26 -0
- package/tsconfig.json +1 -2
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
// Copyright (c) HashiCorp, Inc
|
|
2
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
import { CodeMaker, toCamelCase } from "codemaker";
|
|
4
|
+
import {
|
|
5
|
+
ConstructsMakerProviderTarget,
|
|
6
|
+
ConstructsMakerTarget,
|
|
7
|
+
LANGUAGES,
|
|
8
|
+
logger,
|
|
9
|
+
ProviderSchema,
|
|
10
|
+
TerraformProviderConstraint,
|
|
11
|
+
} from "@cdktn/commons";
|
|
12
|
+
import { FQPN, parseFQPN, ProviderName } from "@cdktn/provider-schema";
|
|
13
|
+
import {
|
|
14
|
+
ProviderFunctionsModel,
|
|
15
|
+
ResourceModel,
|
|
16
|
+
assertNoFunctionsGetterCollision,
|
|
17
|
+
buildProviderFunctionsModel,
|
|
18
|
+
} from "./models";
|
|
19
|
+
import { ResourceParser } from "./resource-parser";
|
|
20
|
+
import {
|
|
21
|
+
ProviderFunctionsEmitter,
|
|
22
|
+
ResourceEmitter,
|
|
23
|
+
StructEmitter,
|
|
24
|
+
} from "./emitter";
|
|
25
|
+
|
|
26
|
+
export interface TerraformProviderGeneratorOptions {
|
|
27
|
+
/**
|
|
28
|
+
* File extension to write on emitted relative imports.
|
|
29
|
+
* Defaults to "" (CommonJS).
|
|
30
|
+
*/
|
|
31
|
+
readonly importExtension?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface ProviderData {
|
|
35
|
+
name: string;
|
|
36
|
+
source: string;
|
|
37
|
+
version: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const isMatching = (
|
|
41
|
+
target: ConstructsMakerTarget,
|
|
42
|
+
terraformSchemaName: string,
|
|
43
|
+
): boolean => {
|
|
44
|
+
if (target.isModule) return false;
|
|
45
|
+
|
|
46
|
+
const elements = terraformSchemaName.split("/");
|
|
47
|
+
|
|
48
|
+
if (elements.length === 1) {
|
|
49
|
+
return target.source === terraformSchemaName;
|
|
50
|
+
} else {
|
|
51
|
+
const [hostname, namespace, provider] = elements;
|
|
52
|
+
|
|
53
|
+
if (!hostname || !namespace || !provider) {
|
|
54
|
+
throw new Error(`can't handle ${terraformSchemaName}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// If target.source is set, try to match it
|
|
58
|
+
if (target.source) {
|
|
59
|
+
const targetSource = {
|
|
60
|
+
// defaults
|
|
61
|
+
hostname: "registry.terraform.io",
|
|
62
|
+
namespace: "hashicorp",
|
|
63
|
+
name: "",
|
|
64
|
+
};
|
|
65
|
+
const targetElements = target.source.split("/");
|
|
66
|
+
// Only a 3-part source explicitly pins a registry hostname. Shorthand
|
|
67
|
+
// sources (e.g. "hashicorp/awscc") omit it, so we must not assume a
|
|
68
|
+
// default: Terraform resolves them under registry.terraform.io while
|
|
69
|
+
// OpenTofu resolves them under registry.opentofu.org. Comparing against a
|
|
70
|
+
// hard-coded default would make schema lookup fail under OpenTofu even
|
|
71
|
+
// though the provider was installed correctly.
|
|
72
|
+
const explicitHostname = targetElements.length === 3;
|
|
73
|
+
switch (targetElements.length) {
|
|
74
|
+
case 1: // only name set
|
|
75
|
+
targetSource.name = targetElements[0].toLowerCase();
|
|
76
|
+
break;
|
|
77
|
+
case 2: // namespace and name set
|
|
78
|
+
targetSource.namespace = targetElements[0].toLowerCase();
|
|
79
|
+
targetSource.name = targetElements[1].toLowerCase();
|
|
80
|
+
break;
|
|
81
|
+
case 3: // hostname, namespace and name set
|
|
82
|
+
targetSource.hostname = targetElements[0].toLowerCase();
|
|
83
|
+
targetSource.namespace = targetElements[1].toLowerCase();
|
|
84
|
+
targetSource.name = targetElements[2].toLowerCase();
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
throw new Error(
|
|
88
|
+
`can't handle ${target.source}. Expected string with 1, 2 or 3 elements separated by '/'`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
(!explicitHostname || targetSource.hostname === hostname) &&
|
|
94
|
+
targetSource.namespace === namespace &&
|
|
95
|
+
targetSource.name === provider
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Else, try to match target.name to the provider name
|
|
100
|
+
|
|
101
|
+
return target.name === provider;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export interface ProviderConstraints {
|
|
106
|
+
[fqn: string]: ProviderData;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export class TerraformProviderGenerator {
|
|
110
|
+
private resourceParser = new ResourceParser();
|
|
111
|
+
private resourceEmitter: ResourceEmitter;
|
|
112
|
+
private structEmitter: StructEmitter;
|
|
113
|
+
private providerFunctionsEmitter: ProviderFunctionsEmitter;
|
|
114
|
+
private readonly importExtension: string;
|
|
115
|
+
public versions: { [fqpn: string]: string | undefined } = {};
|
|
116
|
+
|
|
117
|
+
constructor(
|
|
118
|
+
private readonly code: CodeMaker,
|
|
119
|
+
private readonly schema: ProviderSchema,
|
|
120
|
+
options: TerraformProviderGeneratorOptions = {},
|
|
121
|
+
) {
|
|
122
|
+
this.code.indentation = 2;
|
|
123
|
+
this.importExtension = options.importExtension ?? "";
|
|
124
|
+
this.resourceEmitter = new ResourceEmitter(this.code, this.importExtension);
|
|
125
|
+
this.structEmitter = new StructEmitter(this.code, this.importExtension);
|
|
126
|
+
this.providerFunctionsEmitter = new ProviderFunctionsEmitter(this.code);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private getProviderByConstraint(
|
|
130
|
+
providerConstraint: ConstructsMakerTarget,
|
|
131
|
+
): FQPN | undefined {
|
|
132
|
+
return Object.keys(this.schema.provider_schemas || {}).find((fqpn) =>
|
|
133
|
+
isMatching(providerConstraint, fqpn),
|
|
134
|
+
) as FQPN | undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public generate(providerConstraint: ConstructsMakerTarget) {
|
|
138
|
+
const fqpn = this.getProviderByConstraint(providerConstraint);
|
|
139
|
+
if (!fqpn) {
|
|
140
|
+
logger.debug(
|
|
141
|
+
`Could not find provider constraint for ${providerConstraint} in schema: ${JSON.stringify(
|
|
142
|
+
this.schema,
|
|
143
|
+
null,
|
|
144
|
+
2,
|
|
145
|
+
)}`,
|
|
146
|
+
);
|
|
147
|
+
throw new Error(
|
|
148
|
+
`Could not find provider with constraint ${JSON.stringify(
|
|
149
|
+
providerConstraint,
|
|
150
|
+
)}`,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const providerVersion = this.schema.provider_versions?.[fqpn];
|
|
155
|
+
this.emitProvider(fqpn, providerVersion, providerConstraint);
|
|
156
|
+
this.versions[fqpn] = providerVersion;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public generateAll() {
|
|
160
|
+
for (const fqpn of Object.keys(this.schema.provider_schemas || {})) {
|
|
161
|
+
this.generate(
|
|
162
|
+
new ConstructsMakerProviderTarget(
|
|
163
|
+
new TerraformProviderConstraint(fqpn),
|
|
164
|
+
LANGUAGES[0],
|
|
165
|
+
),
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public async save(outdir: string) {
|
|
171
|
+
await this.code.save(outdir);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public buildResourceModels(
|
|
175
|
+
fqpn: FQPN,
|
|
176
|
+
constraint?: ConstructsMakerTarget,
|
|
177
|
+
): ResourceModel[] {
|
|
178
|
+
const provider = this.schema.provider_schemas?.[fqpn];
|
|
179
|
+
if (!provider) {
|
|
180
|
+
throw new Error(`Can not find provider '${fqpn}' in schema`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const resources = Object.entries(provider.resource_schemas || {}).map(
|
|
184
|
+
([type, resource]) =>
|
|
185
|
+
this.resourceParser.parse(fqpn, type, resource, "resource", constraint),
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const dataSources = Object.entries(provider.data_source_schemas || {}).map(
|
|
189
|
+
([type, resource]) =>
|
|
190
|
+
this.resourceParser.parse(
|
|
191
|
+
fqpn,
|
|
192
|
+
`data_${type}`,
|
|
193
|
+
resource,
|
|
194
|
+
"data_source",
|
|
195
|
+
constraint,
|
|
196
|
+
),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const ephemeralResources = Object.entries(
|
|
200
|
+
provider.ephemeral_resource_schemas || {},
|
|
201
|
+
).map(([type, resource]) =>
|
|
202
|
+
this.resourceParser.parse(
|
|
203
|
+
fqpn,
|
|
204
|
+
`ephemeral_${type}`,
|
|
205
|
+
resource,
|
|
206
|
+
"ephemeral_resource",
|
|
207
|
+
constraint,
|
|
208
|
+
),
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// CRITICAL: ephemeral resources must be appended AFTER resources and data
|
|
212
|
+
// sources - uniqueClassName dedup is order-dependent and existing
|
|
213
|
+
// prebuilt snapshots must not churn.
|
|
214
|
+
return ([] as ResourceModel[]).concat(
|
|
215
|
+
...resources,
|
|
216
|
+
...dataSources,
|
|
217
|
+
...ephemeralResources,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public getClassNameForResource(terraformType: string) {
|
|
222
|
+
return this.resourceParser.getClassNameForResource(terraformType);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
public getNamespaceNameForResource(terraformType: string) {
|
|
226
|
+
return this.resourceParser.getNamespaceNameForResource(terraformType);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private emitProvider(
|
|
230
|
+
fqpn: FQPN,
|
|
231
|
+
providerVersion?: string,
|
|
232
|
+
constraint?: ConstructsMakerTarget,
|
|
233
|
+
) {
|
|
234
|
+
const name = constraint?.name
|
|
235
|
+
? (constraint.name as ProviderName)
|
|
236
|
+
: parseFQPN(fqpn).name;
|
|
237
|
+
const provider = this.schema.provider_schemas?.[fqpn];
|
|
238
|
+
if (!provider) {
|
|
239
|
+
throw new Error(`Can not find provider '${fqpn}' in schema`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const files: string[] = [];
|
|
243
|
+
this.buildResourceModels(fqpn, constraint).forEach((resourceModel) => {
|
|
244
|
+
if (constraint) {
|
|
245
|
+
resourceModel.providerVersionConstraint = constraint.version;
|
|
246
|
+
resourceModel.terraformProviderSource = constraint.source;
|
|
247
|
+
}
|
|
248
|
+
resourceModel.providerVersion = providerVersion;
|
|
249
|
+
|
|
250
|
+
if (resourceModel.structsRequireSharding) {
|
|
251
|
+
files.push(this.emitResourceWithComplexStruct(resourceModel));
|
|
252
|
+
} else {
|
|
253
|
+
files.push(this.emitResource(resourceModel));
|
|
254
|
+
}
|
|
255
|
+
this.emitResourceReadme(resourceModel);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Built before the provider class is emitted (rather than after, as
|
|
259
|
+
// resources/data sources/ephemeral resources above already are) so that
|
|
260
|
+
// the model can be attached to providerResource and picked up by
|
|
261
|
+
// ResourceEmitter while it still emits the provider class file below -
|
|
262
|
+
// see the engineering brief for why this ordering matters.
|
|
263
|
+
const providerFunctionsModel = buildProviderFunctionsModel(
|
|
264
|
+
name,
|
|
265
|
+
provider.functions,
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
if (provider.provider) {
|
|
269
|
+
const providerResource = this.resourceParser.parse(
|
|
270
|
+
fqpn,
|
|
271
|
+
`provider`,
|
|
272
|
+
provider.provider,
|
|
273
|
+
"provider",
|
|
274
|
+
constraint,
|
|
275
|
+
);
|
|
276
|
+
if (constraint) {
|
|
277
|
+
providerResource.providerVersionConstraint = constraint.version;
|
|
278
|
+
providerResource.terraformProviderSource = constraint.source;
|
|
279
|
+
providerResource.terraformProviderName = constraint.name;
|
|
280
|
+
}
|
|
281
|
+
providerResource.providerVersion = providerVersion;
|
|
282
|
+
|
|
283
|
+
if (providerFunctionsModel) {
|
|
284
|
+
assertNoFunctionsGetterCollision(
|
|
285
|
+
name,
|
|
286
|
+
providerResource.attributes.map((att) => att.name),
|
|
287
|
+
);
|
|
288
|
+
providerResource.providerFunctionsModel = providerFunctionsModel;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
files.push(this.emitResource(providerResource));
|
|
292
|
+
this.emitResourceReadme(providerResource);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (providerFunctionsModel) {
|
|
296
|
+
files.push(this.emitProviderFunctions(name, providerFunctionsModel));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
this.emitIndexFile(name, files);
|
|
300
|
+
this.emitLazyIndexFile(name, files);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private emitProviderFunctions(
|
|
304
|
+
provider: ProviderName,
|
|
305
|
+
model: ProviderFunctionsModel,
|
|
306
|
+
): string {
|
|
307
|
+
const filePath = `providers/${provider}/provider-functions/index.ts`;
|
|
308
|
+
this.code.openFile(filePath);
|
|
309
|
+
this.code.line(`// generated from provider function schema`);
|
|
310
|
+
this.code.line();
|
|
311
|
+
this.providerFunctionsEmitter.emit(model);
|
|
312
|
+
this.code.closeFile(filePath);
|
|
313
|
+
return filePath;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private emitResourceReadme(resource: ResourceModel): void {
|
|
317
|
+
const filePath = `${resource.namespaceFolderPath}/README.md`;
|
|
318
|
+
this.code.openFile(filePath);
|
|
319
|
+
this.code.line(`# \`${resource.terraformType}\``);
|
|
320
|
+
this.code.line();
|
|
321
|
+
const type = resource.isProvider
|
|
322
|
+
? resource.provider
|
|
323
|
+
: resource.terraformType;
|
|
324
|
+
this.code.line(
|
|
325
|
+
`Refer to the Terraform Registry for docs: [\`${type}\`](${resource.linkToDocs}).`,
|
|
326
|
+
);
|
|
327
|
+
this.code.closeFile(filePath);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private emitIndexFile(provider: ProviderName, files: string[]): void {
|
|
331
|
+
const folder = `providers/${provider}`;
|
|
332
|
+
const filePath = `${folder}/index.ts`;
|
|
333
|
+
this.code.openFile(filePath);
|
|
334
|
+
this.code.line("// generated by cdktn get");
|
|
335
|
+
for (const file of files) {
|
|
336
|
+
const dirName = file.replace(`${folder}/`, "").replace("/index.ts", "");
|
|
337
|
+
this.code.line(
|
|
338
|
+
`export * as ${toCamelCase(dirName)} from './${dirName}/index${this.importExtension}';`,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
this.code.line();
|
|
342
|
+
this.code.closeFile(filePath);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private emitLazyIndexFile(provider: ProviderName, files: string[]): void {
|
|
346
|
+
const folder = `providers/${provider}`;
|
|
347
|
+
const filePath = `${folder}/lazy-index.ts`;
|
|
348
|
+
this.code.openFile(filePath);
|
|
349
|
+
this.code.line("// generated by cdktn get");
|
|
350
|
+
for (const file of files) {
|
|
351
|
+
const dirName = file.replace(`${folder}/`, "").replace("/index.ts", "");
|
|
352
|
+
this.code.line(
|
|
353
|
+
`Object.defineProperty(exports, '${toCamelCase(
|
|
354
|
+
dirName,
|
|
355
|
+
)}', { get: function () { return require('./${dirName}'); } });`,
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
this.code.line();
|
|
359
|
+
this.code.closeFile(filePath);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private emitResource(resource: ResourceModel): string {
|
|
363
|
+
this.code.openFile(resource.filePath);
|
|
364
|
+
this.emitFileHeader(resource);
|
|
365
|
+
this.structEmitter.emit(resource);
|
|
366
|
+
this.resourceEmitter.emit(resource);
|
|
367
|
+
this.code.closeFile(resource.filePath);
|
|
368
|
+
|
|
369
|
+
return resource.filePath;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
private emitResourceWithComplexStruct(resource: ResourceModel) {
|
|
373
|
+
const generatedFiles = [];
|
|
374
|
+
|
|
375
|
+
// drop the last segment of the filepath
|
|
376
|
+
const filePath = resource.filePath;
|
|
377
|
+
this.code.openFile(filePath);
|
|
378
|
+
this.code.line(`// generated from terraform resource schema`);
|
|
379
|
+
this.code.line();
|
|
380
|
+
|
|
381
|
+
if (resource.structsRequireSharding) {
|
|
382
|
+
const structsSpecifier = `./${resource.structsFolderName}/index${this.importExtension}`;
|
|
383
|
+
if (resource.referencedTypes.length > 0) {
|
|
384
|
+
this.code.line(
|
|
385
|
+
`import { ${resource.referencedTypes.join(
|
|
386
|
+
", \n",
|
|
387
|
+
)}} from '${structsSpecifier}';`,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
this.code.line(`export * from '${structsSpecifier}';`);
|
|
392
|
+
|
|
393
|
+
resource.importStatements.forEach((statement) =>
|
|
394
|
+
this.code.line(statement),
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
this.structEmitter.emitInterface(resource, resource.configStruct);
|
|
398
|
+
this.resourceEmitter.emit(resource);
|
|
399
|
+
|
|
400
|
+
this.code.closeFile(filePath);
|
|
401
|
+
|
|
402
|
+
this.structEmitter.emit(resource);
|
|
403
|
+
generatedFiles.push(resource.fileName);
|
|
404
|
+
generatedFiles.push(resource.structsFolderName);
|
|
405
|
+
} else {
|
|
406
|
+
resource.importStatements.forEach((statement) =>
|
|
407
|
+
this.code.line(statement),
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
this.structEmitter.emit(resource);
|
|
411
|
+
this.resourceEmitter.emit(resource);
|
|
412
|
+
this.code.closeFile(filePath);
|
|
413
|
+
generatedFiles.push(resource.fileName);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return filePath;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private emitFileHeader(resource: ResourceModel) {
|
|
420
|
+
this.code.line(`// ${resource.linkToDocs}`);
|
|
421
|
+
this.code.line(`// generated from terraform resource schema`);
|
|
422
|
+
this.code.line();
|
|
423
|
+
resource.importStatements.forEach((statement) => this.code.line(statement));
|
|
424
|
+
this.code.line();
|
|
425
|
+
this.code.line("// Configuration");
|
|
426
|
+
this.code.line();
|
|
427
|
+
}
|
|
428
|
+
}
|