@cdktn/provider-generator 0.24.0-pre.5 → 0.24.0-pre.50

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 (67) 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/constructs-maker.d.ts +5 -1
  9. package/build/get/constructs-maker.js +14 -6
  10. package/build/get/generator/emitter/struct-emitter.d.ts +2 -1
  11. package/build/get/generator/emitter/struct-emitter.js +14 -11
  12. package/build/get/generator/module-generator.js +3 -3
  13. package/build/get/generator/provider-generator.d.ts +9 -1
  14. package/build/get/generator/provider-generator.js +9 -6
  15. package/jest.config.js +16 -9
  16. package/package.json +24 -23
  17. package/package.sh +1 -1
  18. package/src/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +8 -8
  19. package/src/__tests__/__snapshots__/provider.test.ts.snap +2951 -2951
  20. package/src/__tests__/edge-provider-schema/builder.ts +185 -0
  21. package/src/__tests__/edge-provider-schema/cli.ts +51 -0
  22. package/src/__tests__/edge-provider-schema/index.ts +161 -0
  23. package/src/__tests__/edge-provider-schema.test.ts +24 -0
  24. package/src/__tests__/provider.test.ts +180 -0
  25. package/src/get/__tests__/constructs-maker.test.ts +118 -0
  26. package/src/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +5 -5
  27. package/src/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +3310 -3310
  28. package/src/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +355 -355
  29. package/src/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +8 -8
  30. package/src/get/__tests__/generator/__snapshots__/provider.test.ts.snap +8 -8
  31. package/src/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +126 -126
  32. package/src/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +17 -17
  33. package/src/get/__tests__/generator/__snapshots__/types.test.ts.snap +65 -65
  34. package/src/get/__tests__/generator/complex-computed-types.test.ts +28 -0
  35. package/src/get/__tests__/generator/deep-nested-attributes.test.ts +56 -0
  36. package/src/get/__tests__/generator/description-escaping.test.ts +84 -0
  37. package/src/get/__tests__/generator/empty-provider-resources.test.ts +26 -0
  38. package/src/get/__tests__/generator/export-sharding.test.ts +169 -0
  39. package/src/get/__tests__/generator/import-style.test.ts +129 -0
  40. package/src/get/__tests__/generator/module-generator.test.ts +528 -0
  41. package/src/get/__tests__/generator/nested-types.test.ts +54 -0
  42. package/src/get/__tests__/generator/provider.test.ts +51 -0
  43. package/src/get/__tests__/generator/resource-types.test.ts +118 -0
  44. package/src/get/__tests__/generator/skipped-attributes.test.ts +72 -0
  45. package/src/get/__tests__/generator/types.test.ts +611 -0
  46. package/src/get/__tests__/generator/versions-file.test.ts +72 -0
  47. package/src/get/__tests__/util.ts +75 -0
  48. package/src/get/constructs-maker.ts +822 -0
  49. package/src/get/generator/custom-defaults.ts +493 -0
  50. package/src/get/generator/emitter/attributes-emitter.ts +225 -0
  51. package/src/get/generator/emitter/index.ts +5 -0
  52. package/src/get/generator/emitter/resource-emitter.ts +226 -0
  53. package/src/get/generator/emitter/struct-emitter.ts +683 -0
  54. package/src/get/generator/loop-detection.ts +81 -0
  55. package/src/get/generator/models/attribute-model.ts +216 -0
  56. package/src/get/generator/models/attribute-type-model.ts +448 -0
  57. package/src/get/generator/models/index.ts +7 -0
  58. package/src/get/generator/models/resource-model.ts +161 -0
  59. package/src/get/generator/models/scope.ts +54 -0
  60. package/src/get/generator/models/struct.ts +116 -0
  61. package/src/get/generator/module-generator.ts +234 -0
  62. package/src/get/generator/provider-generator.ts +355 -0
  63. package/src/get/generator/resource-parser.ts +762 -0
  64. package/src/get/generator/sanitized-comments.ts +49 -0
  65. package/src/get/generator/skipped-attributes.ts +27 -0
  66. package/src/index.ts +40 -0
  67. package/src/util.ts +26 -0
@@ -0,0 +1,448 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import { Struct } from "./struct";
4
+ import { uppercaseFirst, downcaseFirst } from "../../../util";
5
+
6
+ export interface AttributeTypeModel {
7
+ readonly struct?: Struct; // complex object type contained within the type
8
+ readonly isComplex: boolean; // basically the same as having a struct
9
+ getStoredClassInitializer(name: string): string; // initializer for keeping class needed to keep track of reference access
10
+ readonly storedClassType: string; // used mainly by collection types to generate their stored class initializer
11
+ readonly inputTypeDefinition: string; // this is the type used for inputting values
12
+ getAttributeAccessFunction(name: string): string; // this is for getting reference for simple types
13
+ readonly toTerraformFunction: string; // this is for converting input values to Terraform syntax
14
+ readonly toHclTerraformFunction: string; // this is for converting input values to Terraform syntax in HCL
15
+ readonly typeModelType: string; // so we don't need to use instanceof
16
+ readonly hasReferenceClass: boolean; // used to determine if a stored_class getter should be used
17
+ readonly isTokenizable: boolean; // can the type be represented by a token type
18
+ }
19
+
20
+ export class SkippedAttributeTypeModel implements AttributeTypeModel {
21
+ constructor() {}
22
+
23
+ get typeModelType() {
24
+ return "simple";
25
+ }
26
+
27
+ get struct() {
28
+ return undefined;
29
+ }
30
+
31
+ get isComplex() {
32
+ return false;
33
+ }
34
+
35
+ getStoredClassInitializer(_name: string) {
36
+ // not used
37
+ return "";
38
+ }
39
+
40
+ get storedClassType() {
41
+ return "any";
42
+ }
43
+
44
+ get inputTypeDefinition() {
45
+ return "any";
46
+ }
47
+
48
+ getAttributeAccessFunction(name: string) {
49
+ return `this.interpolationForAttribute('${name}')`;
50
+ }
51
+
52
+ get toTerraformFunction() {
53
+ return `cdktn.anyToTerraform`;
54
+ }
55
+
56
+ get toHclTerraformFunction() {
57
+ return `cdktn.anyToHclTerraform`;
58
+ }
59
+
60
+ get hasReferenceClass() {
61
+ return false;
62
+ }
63
+
64
+ get isTokenizable() {
65
+ return false;
66
+ }
67
+ }
68
+
69
+ export class SimpleAttributeTypeModel implements AttributeTypeModel {
70
+ constructor(public readonly type: string) {}
71
+
72
+ get typeModelType() {
73
+ return "simple";
74
+ }
75
+
76
+ get struct() {
77
+ return undefined;
78
+ }
79
+
80
+ get isComplex() {
81
+ return false;
82
+ }
83
+
84
+ getStoredClassInitializer(_name: string) {
85
+ // not used
86
+ return "";
87
+ }
88
+
89
+ get storedClassType() {
90
+ return this.type;
91
+ }
92
+
93
+ get inputTypeDefinition() {
94
+ if (this.type === "boolean") {
95
+ return "boolean | cdktn.IResolvable";
96
+ } else {
97
+ return this.type;
98
+ }
99
+ }
100
+
101
+ getAttributeAccessFunction(name: string) {
102
+ return `this.get${uppercaseFirst(this.type)}Attribute('${name}')`;
103
+ }
104
+
105
+ get toTerraformFunction() {
106
+ return `cdktn.${this.type}ToTerraform`;
107
+ }
108
+
109
+ get toHclTerraformFunction() {
110
+ return `cdktn.${this.type}ToHclTerraform`;
111
+ }
112
+
113
+ get hasReferenceClass() {
114
+ return false;
115
+ }
116
+
117
+ get isTokenizable() {
118
+ return true;
119
+ }
120
+ }
121
+
122
+ export class StructAttributeTypeModel implements AttributeTypeModel {
123
+ constructor(public readonly struct: Struct) {}
124
+
125
+ get typeModelType() {
126
+ return "struct";
127
+ }
128
+
129
+ get isComplex() {
130
+ return true;
131
+ }
132
+
133
+ getStoredClassInitializer(name: string) {
134
+ return `new ${this.struct.outputReferenceName}(this, "${name}")`;
135
+ }
136
+
137
+ get storedClassType() {
138
+ return this.struct.name;
139
+ }
140
+
141
+ get inputTypeDefinition() {
142
+ return this.struct.name;
143
+ }
144
+
145
+ getAttributeAccessFunction(name: string) {
146
+ // This shouln't actually be called
147
+ return `this.interpolationForAttribute('${name}')`;
148
+ }
149
+
150
+ get toTerraformFunction() {
151
+ return `${downcaseFirst(this.struct.name)}ToTerraform`;
152
+ }
153
+
154
+ get toHclTerraformFunction() {
155
+ return `${downcaseFirst(this.struct.name)}ToHclTerraform`;
156
+ }
157
+
158
+ get hasReferenceClass() {
159
+ return true;
160
+ }
161
+
162
+ get isTokenizable() {
163
+ return false;
164
+ }
165
+ }
166
+
167
+ export interface CollectionAttributeTypeModel extends AttributeTypeModel {
168
+ elementType: AttributeTypeModel;
169
+ }
170
+
171
+ export class ListAttributeTypeModel implements CollectionAttributeTypeModel {
172
+ constructor(
173
+ public readonly elementType: AttributeTypeModel,
174
+ public readonly isSingleItem: boolean,
175
+ private readonly isBlock: boolean,
176
+ ) {
177
+ if (this.struct) {
178
+ this.struct.isSingleItem = this.isSingleItem || false;
179
+ }
180
+ }
181
+
182
+ get typeModelType() {
183
+ return "list";
184
+ }
185
+
186
+ get struct() {
187
+ return this.elementType.struct;
188
+ }
189
+
190
+ get isComplex() {
191
+ return this.elementType.isComplex;
192
+ }
193
+
194
+ getStoredClassInitializer(name: string) {
195
+ if (this.isSingleItem) {
196
+ return `new ${this.elementType.storedClassType}OutputReference(this, "${name}")`;
197
+ } else {
198
+ if (this.isComplex) {
199
+ return `new ${this.storedClassType}(this, "${name}", false)`;
200
+ } else {
201
+ return `new cdktn.${uppercaseFirst(
202
+ this.storedClassType,
203
+ )}(this, "${name}", false)`;
204
+ }
205
+ }
206
+ }
207
+
208
+ get storedClassType() {
209
+ return `${this.elementType.storedClassType}List`;
210
+ }
211
+
212
+ get inputTypeDefinition() {
213
+ if (this.isSingleItem) {
214
+ return this.elementType.inputTypeDefinition;
215
+ } else if (this.elementType.storedClassType === "boolean") {
216
+ return "Array<boolean | cdktn.IResolvable> | cdktn.IResolvable";
217
+ } else if (this.isComplex) {
218
+ return `${this.elementType.storedClassType}[] | cdktn.IResolvable`;
219
+ } else if (this.elementType.typeModelType !== "simple") {
220
+ return `${this.elementType.inputTypeDefinition}[] | cdktn.IResolvable`;
221
+ } else {
222
+ return `${this.elementType.inputTypeDefinition}[]`;
223
+ }
224
+ }
225
+
226
+ getAttributeAccessFunction(name: string) {
227
+ switch (this.elementType.storedClassType) {
228
+ case "string":
229
+ return `this.getListAttribute('${name}')`;
230
+ case "number":
231
+ return `this.getNumberListAttribute('${name}')`;
232
+ }
233
+
234
+ return `this.interpolationForAttribute('${name}')`;
235
+ }
236
+
237
+ get toTerraformFunction() {
238
+ if (this.isSingleItem) {
239
+ return this.elementType.toTerraformFunction;
240
+ }
241
+ return `cdktn.listMapper(${this.elementType.toTerraformFunction}, ${this.isBlock})`;
242
+ }
243
+
244
+ get toHclTerraformFunction() {
245
+ if (this.isSingleItem) {
246
+ return this.elementType.toHclTerraformFunction;
247
+ }
248
+
249
+ return `cdktn.listMapperHcl(${this.elementType.toHclTerraformFunction}, ${this.isBlock})`;
250
+ }
251
+
252
+ get hasReferenceClass() {
253
+ return this.isSingleItem || this.isComplex;
254
+ }
255
+
256
+ get isTokenizable() {
257
+ switch (this.elementType.storedClassType) {
258
+ case "string":
259
+ return true;
260
+ case "number":
261
+ return true;
262
+ default:
263
+ return false;
264
+ }
265
+ }
266
+ }
267
+
268
+ export class SetAttributeTypeModel implements CollectionAttributeTypeModel {
269
+ constructor(
270
+ public readonly elementType: AttributeTypeModel,
271
+ public readonly isSingleItem: boolean,
272
+ private readonly isBlock: boolean,
273
+ ) {
274
+ if (this.struct) {
275
+ this.struct.isSingleItem = this.isSingleItem || false;
276
+ }
277
+ }
278
+
279
+ get typeModelType() {
280
+ return "set";
281
+ }
282
+
283
+ get struct() {
284
+ return this.elementType.struct;
285
+ }
286
+
287
+ get isComplex() {
288
+ return this.elementType.isComplex;
289
+ }
290
+
291
+ getStoredClassInitializer(name: string) {
292
+ if (this.isSingleItem) {
293
+ return `new ${this.elementType.storedClassType}OutputReference(this, "${name}")`;
294
+ } else {
295
+ if (this.isComplex) {
296
+ return `new ${this.storedClassType}(this, "${name}", true)`;
297
+ } else {
298
+ return `new cdktn.${uppercaseFirst(
299
+ this.storedClassType,
300
+ )}(this, "${name}", true)`;
301
+ }
302
+ }
303
+ }
304
+
305
+ get storedClassType() {
306
+ return `${this.elementType.storedClassType}List`;
307
+ }
308
+
309
+ get inputTypeDefinition() {
310
+ if (this.isSingleItem) {
311
+ return this.elementType.inputTypeDefinition;
312
+ } else if (this.elementType.storedClassType === "boolean") {
313
+ return "Array<boolean | cdktn.IResolvable> | cdktn.IResolvable";
314
+ } else if (this.isComplex) {
315
+ return `${this.elementType.storedClassType}[] | cdktn.IResolvable`;
316
+ } else if (this.elementType.typeModelType !== "simple") {
317
+ return `${this.elementType.inputTypeDefinition}[] | cdktn.IResolvable`;
318
+ } else {
319
+ return `${this.elementType.inputTypeDefinition}[]`;
320
+ }
321
+ }
322
+
323
+ getAttributeAccessFunction(name: string) {
324
+ switch (this.elementType.storedClassType) {
325
+ case "string":
326
+ return `cdktn.Fn.tolist(this.getListAttribute('${name}'))`;
327
+ case "number":
328
+ return `cdktn.Token.asNumberList(cdktn.Fn.tolist(this.getNumberListAttribute('${name}')))`;
329
+ }
330
+
331
+ // Token.asAny is required because tolist returns an Array encoded token which the listMapper
332
+ // would try to map over when this is passed to another resource. With Token.asAny() it is left
333
+ // as is by the listMapper and is later properly resolved to a reference
334
+ // (this only works in TypeScript currently, same as for referencing lists
335
+ // [see "interpolationForAttribute(...)" further below])
336
+ return `cdktn.Token.asAny(cdktn.Fn.tolist(this.interpolationForAttribute('${name}')))`;
337
+ }
338
+
339
+ get toTerraformFunction() {
340
+ if (this.isSingleItem) {
341
+ return this.elementType.toTerraformFunction;
342
+ } else {
343
+ return `cdktn.listMapper(${this.elementType.toTerraformFunction}, ${this.isBlock})`;
344
+ }
345
+ }
346
+
347
+ get toHclTerraformFunction() {
348
+ if (this.isSingleItem) {
349
+ return this.elementType.toHclTerraformFunction;
350
+ }
351
+ return `cdktn.listMapperHcl(${this.elementType.toHclTerraformFunction}, ${this.isBlock})`;
352
+ }
353
+
354
+ get hasReferenceClass() {
355
+ return this.isSingleItem || this.isComplex;
356
+ }
357
+
358
+ get isTokenizable() {
359
+ switch (this.elementType.storedClassType) {
360
+ case "string":
361
+ return true;
362
+ case "number":
363
+ return true;
364
+ default:
365
+ return false;
366
+ }
367
+ }
368
+ }
369
+
370
+ export class MapAttributeTypeModel implements CollectionAttributeTypeModel {
371
+ constructor(public readonly elementType: AttributeTypeModel) {}
372
+
373
+ get typeModelType() {
374
+ return "map";
375
+ }
376
+
377
+ get struct() {
378
+ return this.elementType.struct;
379
+ }
380
+
381
+ get isComplex() {
382
+ return this.elementType.isComplex;
383
+ }
384
+
385
+ getStoredClassInitializer(name: string) {
386
+ if (this.isComplex) {
387
+ return `new ${this.storedClassType}(this, "${name}")`;
388
+ } else {
389
+ return `new cdktn.${uppercaseFirst(
390
+ this.storedClassType,
391
+ )}(this, "${name}")`;
392
+ }
393
+ }
394
+
395
+ get storedClassType() {
396
+ return `${this.elementType.storedClassType}Map`;
397
+ }
398
+
399
+ get inputTypeDefinition() {
400
+ // map of booleans has token support, but booleans don't
401
+ if (this.elementType.storedClassType === "boolean") {
402
+ return `{ [key: string]: (${this.elementType.storedClassType} | cdktn.IResolvable) }`;
403
+ } else if (this.isComplex) {
404
+ return `{ [key: string]: ${this.elementType.storedClassType} } | cdktn.IResolvable`;
405
+ } else if (this.elementType.typeModelType !== "simple") {
406
+ return `{ [key: string]: ${this.elementType.inputTypeDefinition} } | cdktn.IResolvable`;
407
+ } else {
408
+ return `{ [key: string]: ${this.elementType.storedClassType} }`;
409
+ }
410
+ }
411
+
412
+ getAttributeAccessFunction(name: string) {
413
+ if (!this.isComplex && this.elementType.typeModelType !== "simple") {
414
+ return `this.interpolationForAttribute('${name}')`;
415
+ }
416
+
417
+ return `this.get${uppercaseFirst(
418
+ this.storedClassType,
419
+ )}Attribute('${name}')`;
420
+ }
421
+
422
+ get toTerraformFunction() {
423
+ return `cdktn.hashMapper(${this.elementType.toTerraformFunction})`;
424
+ }
425
+
426
+ get toHclTerraformFunction() {
427
+ return `cdktn.hashMapperHcl(${this.elementType.toHclTerraformFunction})`;
428
+ }
429
+
430
+ get hasReferenceClass() {
431
+ return this.isComplex;
432
+ }
433
+
434
+ get isTokenizable() {
435
+ switch (this.elementType.storedClassType) {
436
+ case "string":
437
+ return true;
438
+ case "number":
439
+ return true;
440
+ case "boolean":
441
+ return true;
442
+ case "any":
443
+ return true;
444
+ default:
445
+ return false;
446
+ }
447
+ }
448
+ }
@@ -0,0 +1,7 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ export * from "./attribute-model";
4
+ export * from "./attribute-type-model";
5
+ export * from "./resource-model";
6
+ export * from "./scope";
7
+ export * from "./struct";
@@ -0,0 +1,161 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import { toSnakeCase } from "codemaker";
4
+ import path from "path";
5
+ import { FQPN, parseFQPN, ProviderName } from "@cdktn/provider-schema";
6
+ import { AttributeModel } from "./attribute-model";
7
+ import { Struct, ConfigStruct } from "./struct";
8
+ import { Schema } from "@cdktn/commons";
9
+
10
+ // Limit is 1200 to prevent stack size error.
11
+ // Could increase now that calculation is more accurate;
12
+ // however, probably better to have smaller
13
+ export const STRUCT_SHARDING_THRESHOLD = 400;
14
+
15
+ interface ResourceModelOptions {
16
+ terraformType: string;
17
+ className: string;
18
+ baseName: string;
19
+ fileName: string;
20
+ filePath: string;
21
+ attributes: AttributeModel[];
22
+ structs: Struct[];
23
+ fqpn: FQPN;
24
+ schema: Schema;
25
+ terraformSchemaType: string;
26
+ configStructName: string;
27
+ }
28
+
29
+ type DefinitionPath = string;
30
+ export class ResourceModel {
31
+ public className: string;
32
+ public filePath: string;
33
+ public terraformType: string;
34
+ public baseName: string;
35
+ public provider: ProviderName;
36
+ public fqpn: FQPN;
37
+ public providerVersionConstraint?: string;
38
+ public providerVersion?: string;
39
+ public terraformProviderSource?: string;
40
+ /*
41
+ * usually same as provider, but can be overridden if user picks a different name
42
+ * to be able to use two providers with the same name
43
+ */
44
+ public terraformProviderName: string;
45
+ public fileName: string;
46
+ public attributes: AttributeModel[];
47
+ public schema: Schema;
48
+ private _structs: Struct[];
49
+ private dependencies: string[];
50
+ private terraformSchemaType: string;
51
+ private configStructName: string;
52
+ public readonly structsRequireSharding: boolean;
53
+ public recursiveAttributePaths: { [usagePath: string]: DefinitionPath } = {};
54
+
55
+ constructor(options: ResourceModelOptions) {
56
+ this.className = options.className;
57
+ this.filePath = options.filePath;
58
+ this.terraformType = options.terraformType;
59
+ this.baseName = options.baseName;
60
+ this.attributes = options.attributes;
61
+ this.schema = options.schema;
62
+ this.fqpn = options.fqpn;
63
+ this.provider = parseFQPN(options.fqpn).name;
64
+ this.terraformProviderName = this.provider;
65
+ this.fileName = options.fileName;
66
+ this._structs = options.structs;
67
+ this.terraformSchemaType = options.terraformSchemaType;
68
+ this.configStructName = options.configStructName;
69
+ this.dependencies = [
70
+ `import { Construct } from 'constructs';`,
71
+ `import * as cdktn from 'cdktn';`,
72
+ ];
73
+
74
+ this.structsRequireSharding =
75
+ this._structs.reduce((partialSum, s) => partialSum + s.exportCount, 0) >
76
+ STRUCT_SHARDING_THRESHOLD;
77
+ }
78
+
79
+ public get structs(): Struct[] {
80
+ return [this.configStruct, ...this._structs];
81
+ }
82
+
83
+ public get configStruct() {
84
+ return new ConfigStruct(this.configStructName, this.attributes);
85
+ }
86
+
87
+ public get synthesizableAttributes(): AttributeModel[] {
88
+ return this.configStruct.assignableAttributes;
89
+ }
90
+
91
+ public get importStatements(): string[] {
92
+ return this.dependencies;
93
+ }
94
+
95
+ public get schemaAsJson(): string {
96
+ return this.escapeSchema(JSON.stringify(this.schema, undefined, 2));
97
+ }
98
+
99
+ public get linkToDocs(): string {
100
+ const { hostname, namespace, name } = parseFQPN(this.fqpn);
101
+ const version = this.providerVersion || "latest";
102
+ const base = `https://${hostname}/providers/${namespace}/${name}/${version}/docs`;
103
+ if (this.isProvider) return base;
104
+ if (this.isDataSource)
105
+ return `${base}/data-sources/${this.terraformDocName}`;
106
+ return `${base}/resources/${this.terraformDocName}`;
107
+ }
108
+
109
+ public get isProvider(): boolean {
110
+ return this.terraformSchemaType === "provider";
111
+ }
112
+
113
+ public get isDataSource(): boolean {
114
+ return this.terraformSchemaType === "data_source";
115
+ }
116
+
117
+ public get parentClassName(): string {
118
+ return this.isProvider
119
+ ? "TerraformProvider"
120
+ : this.isDataSource
121
+ ? "TerraformDataSource"
122
+ : "TerraformResource";
123
+ }
124
+
125
+ public get terraformResourceType(): string {
126
+ return this.isProvider
127
+ ? this.terraformProviderName
128
+ : this.isDataSource
129
+ ? this.terraformType.replace(/^data_/, "")
130
+ : this.terraformType;
131
+ }
132
+
133
+ public get terraformDocName(): string {
134
+ return toSnakeCase(
135
+ this.terraformResourceType.replace(
136
+ new RegExp(`^${this.provider}_`, "i"),
137
+ "",
138
+ ),
139
+ );
140
+ }
141
+
142
+ public get referencedTypes(): string[] {
143
+ return this.configStruct.referencedTypes;
144
+ }
145
+
146
+ public get structsFolderName(): string {
147
+ return `${path.basename(this.fileName, ".ts")}-structs`;
148
+ }
149
+
150
+ public get structsFolderPath(): string {
151
+ return path.join(this.namespaceFolderPath, this.structsFolderName);
152
+ }
153
+
154
+ public get namespaceFolderPath(): string {
155
+ return this.filePath.split("/").slice(0, -1).join("/");
156
+ }
157
+
158
+ private escapeSchema(schema: string): string {
159
+ return schema.replace(/(\*\/)/gi, `*\\/`);
160
+ }
161
+ }
@@ -0,0 +1,54 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ export interface ScopeProps {
4
+ readonly name: string;
5
+ readonly isProvider: boolean;
6
+ readonly isComputed?: boolean;
7
+ readonly isOptional?: boolean;
8
+ readonly isRequired?: boolean;
9
+ readonly inBlockType?: boolean;
10
+ readonly isNestedType?: boolean;
11
+ readonly parent?: Scope;
12
+ }
13
+
14
+ export class Scope {
15
+ public readonly name: string;
16
+ public readonly provider?: string;
17
+ public readonly parent?: Scope;
18
+ public readonly isProvider: boolean;
19
+ public isComputed: boolean;
20
+ public isOptional: boolean;
21
+ public isRequired: boolean;
22
+ public inBlockType: boolean;
23
+ public isNestedType: boolean;
24
+
25
+ constructor(props: ScopeProps) {
26
+ this.name = props.name;
27
+ this.parent = props.parent;
28
+ this.isProvider = props.isProvider;
29
+ this.isComputed = props.isComputed ?? false;
30
+ this.isOptional = props.isOptional ?? true;
31
+ this.isRequired = props.isRequired ?? false;
32
+ this.inBlockType = props.inBlockType ?? false;
33
+ this.isNestedType = props.isNestedType ?? false;
34
+ }
35
+
36
+ public fullName(attributeName: string) {
37
+ return `${this.baseName}.${attributeName}`;
38
+ }
39
+
40
+ public get baseName() {
41
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
42
+ let scope: Scope | undefined = this;
43
+ let name = "";
44
+ while (scope) {
45
+ if (name === "") {
46
+ name = scope.name;
47
+ } else {
48
+ name = `${scope.name}.${name}`;
49
+ }
50
+ scope = scope.parent;
51
+ }
52
+ return name;
53
+ }
54
+ }