@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,81 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import { AttributeModel } from "./models/attribute-model";
4
+
5
+ type AttributeIdentifier = [string, Set<string>];
6
+ const equalAttributeIdentifiers = (
7
+ x: AttributeIdentifier,
8
+ y: AttributeIdentifier,
9
+ ) =>
10
+ x[0] === y[0] &&
11
+ x[1].size === y[1].size &&
12
+ [...x[1]].every((x) => y[1].has(x));
13
+
14
+ function typeStructure(model: AttributeModel) {
15
+ if (!model.type.isComplex) {
16
+ return model.type.storedClassType;
17
+ }
18
+
19
+ return `<complex:{${model.type.struct?.attributes
20
+ .map((att) => att.name)
21
+ .sort()}}${model.type.typeModelType}>`;
22
+ }
23
+
24
+ function getAttributeIdentifier(model: AttributeModel): AttributeIdentifier {
25
+ return [
26
+ model.terraformName,
27
+ new Set(
28
+ model.type.struct!.attributes.map((a) => `${a.name}:${typeStructure(a)}`),
29
+ ),
30
+ ];
31
+ }
32
+
33
+ /**
34
+ * Detects recursive attribute schemas and returns an Object
35
+ * describing what property should be linking to which class
36
+ */
37
+ export function detectAttributeLoops(attributes: AttributeModel[]): {
38
+ [loopEntrypoint: string]: string; // attribute path to be replaced -> attribute path of the type to replace with
39
+ } {
40
+ // We aproximate a class as a set of attributes names
41
+ // This is not a perfect approximation, but it's good enough for our purposes
42
+ const redirects: Record<string, string> = {};
43
+
44
+ function depthFirstSearch(
45
+ attribute: AttributeModel,
46
+ path: string[] = [],
47
+ knownStructs: { [attributePath: string]: AttributeIdentifier } = {},
48
+ ) {
49
+ const name = attribute.terraformName;
50
+ const struct = attribute.type.struct;
51
+ if (!struct) {
52
+ return;
53
+ }
54
+
55
+ const structIdentifier = getAttributeIdentifier(attribute);
56
+ // Detect if we visited this already
57
+ const visited = Object.entries(knownStructs).find(([, attrIdentifier]) =>
58
+ equalAttributeIdentifiers(structIdentifier, attrIdentifier),
59
+ );
60
+
61
+ if (visited) {
62
+ // We have a loop, we don't need to search deeper
63
+ const toBeReplacedWith = visited[0];
64
+ const toReplace = [...path, name].join(".");
65
+ redirects[toReplace] = toBeReplacedWith;
66
+ } else {
67
+ // Search deeper
68
+ struct.attributes.forEach((a) =>
69
+ depthFirstSearch(a, [...path, name], {
70
+ ...knownStructs,
71
+ // We haven't visited this yet, add it to the list of known structs
72
+ [[...path, name].join(".")]: structIdentifier,
73
+ }),
74
+ );
75
+ }
76
+ }
77
+
78
+ attributes.forEach((attr) => depthFirstSearch(attr));
79
+
80
+ return redirects;
81
+ }
@@ -0,0 +1,216 @@
1
+ // Copyright (c) HashiCorp, Inc
2
+ // SPDX-License-Identifier: MPL-2.0
3
+ import { AttributeTypeModel } from "./attribute-type-model";
4
+
5
+ export type GetterType =
6
+ | { _type: "plain" }
7
+ | {
8
+ _type: "args";
9
+ args: string;
10
+ returnType?: string;
11
+ returnStatement: string;
12
+ }
13
+ | {
14
+ _type: "stored_class";
15
+ };
16
+
17
+ export type SetterType =
18
+ | { _type: "none" }
19
+ | { _type: "set"; type: string }
20
+ | { _type: "put"; type: string }
21
+ | { _type: "stored_class"; type: string };
22
+
23
+ export interface AttributeModelOptions {
24
+ storageName: string; // private property
25
+ name: string;
26
+ type: AttributeTypeModel;
27
+ optional: boolean;
28
+ computed: boolean;
29
+ terraformName: string;
30
+ terraformFullName: string;
31
+ description?: string;
32
+ getAttCall?: string;
33
+ provider: boolean;
34
+ required: boolean;
35
+ forcePlainGetterType?: boolean; // used for skipping attribute type attributes that use the SkippedAttributeTypeModel which returns an interpolation and has no stored type
36
+ }
37
+
38
+ export function escapeAttributeName(name: string) {
39
+ // `self` and `build` doesn't work in as property name in Python
40
+ if (name === "self" || name === "build") return `${name}Attribute`;
41
+ // jsii can't handle `getFoo` properties, since it's incompatible with Java
42
+ if (name.match(/^get[A-Za-z]+/)) return name.replace("get", "fetch");
43
+ // `equals` is a prohibited name in jsii
44
+ if (name === "equals") return "equalTo";
45
+ // `node` is already used by the Constructs base class
46
+ if (name === "node") return "nodeAttribute";
47
+ // `System` shadows built-in types in CSharp (see #1420)
48
+ if (name === "system") return "systemAttribute";
49
+ // `tfResourceType` is already used by resources to distinguish between different resource types
50
+ if (name === "tfResourceType") return `${name}Attribute`;
51
+ // `importFrom` has potential for common name collision with providers
52
+ if (name === "importFrom") return `${name}Attribute`;
53
+ // `move` could have common name collision with providers
54
+ if (name === "moveTo") return `${name}Attribute`;
55
+ // `software` attribute can be confused with the JSII Java runtime package (see #3115)
56
+ if (name === "software") return `${name}Attribute`;
57
+ return name;
58
+ }
59
+
60
+ export class AttributeModel {
61
+ public storageName: string; // private property
62
+ private _name: string;
63
+ public type: AttributeTypeModel;
64
+ public optional: boolean;
65
+ public computed: boolean;
66
+ public terraformName: string;
67
+ public terraformFullName: string;
68
+ private _description?: string;
69
+ public provider: boolean;
70
+ public required: boolean;
71
+ public forcePlainGetterType?: boolean;
72
+
73
+ constructor(options: AttributeModelOptions) {
74
+ this.storageName = options.storageName;
75
+ this._name = options.name;
76
+ this.type = options.type;
77
+ this.optional = options.optional;
78
+ this.computed = options.computed;
79
+ this.terraformName = options.terraformName;
80
+ this.terraformFullName = options.terraformFullName;
81
+ this._description = options.description;
82
+ this.provider = options.provider;
83
+ this.required = options.required;
84
+ this.forcePlainGetterType = options.forcePlainGetterType;
85
+ }
86
+
87
+ public get typeDefinition() {
88
+ const optional = this.optional ? "?" : "";
89
+ return `${this.name}${optional}: ${this.type.inputTypeDefinition}`;
90
+ }
91
+
92
+ public get isAssignable() {
93
+ return this.required || this.optional;
94
+ }
95
+
96
+ public get isOptional(): boolean {
97
+ return this.optional;
98
+ }
99
+
100
+ public get isRequired(): boolean {
101
+ return this.required;
102
+ }
103
+
104
+ public get isProvider(): boolean {
105
+ return this.provider;
106
+ }
107
+
108
+ public get getterType(): GetterType {
109
+ let getterType: GetterType = { _type: "plain" };
110
+
111
+ if (this.forcePlainGetterType) {
112
+ return getterType;
113
+ }
114
+
115
+ if (this.isProvider) {
116
+ return getterType;
117
+ }
118
+
119
+ if (this.type.hasReferenceClass) {
120
+ getterType = {
121
+ _type: "stored_class",
122
+ };
123
+ } else if (
124
+ this.computed &&
125
+ !this.isAssignable &&
126
+ (!this.type.isTokenizable || this.type.typeModelType === "map")
127
+ ) {
128
+ getterType = {
129
+ _type: "stored_class",
130
+ };
131
+ }
132
+
133
+ return getterType;
134
+ }
135
+
136
+ public get isStored(): boolean {
137
+ return this.isAssignable;
138
+ }
139
+
140
+ public get setterType(): SetterType {
141
+ if (!this.isStored) {
142
+ return { _type: "none" };
143
+ }
144
+
145
+ if (this.getterType._type === "stored_class") {
146
+ return {
147
+ _type: "stored_class",
148
+ type: this.type.inputTypeDefinition,
149
+ };
150
+ }
151
+
152
+ return {
153
+ _type: "set",
154
+ type: `${this.type.inputTypeDefinition}${
155
+ this.isProvider ? " | undefined" : ""
156
+ }`,
157
+ };
158
+ }
159
+
160
+ public get name(): string {
161
+ return AttributeModel.escapeName(this._name);
162
+ }
163
+
164
+ public static escapeName(name: string): string {
165
+ return escapeAttributeName(name);
166
+ }
167
+
168
+ public get description(): string | undefined {
169
+ return this._description?.replace(/'''/gi, "```");
170
+ }
171
+
172
+ public getReferencedTypes(isConfigStruct: boolean): string[] | undefined {
173
+ const attTypeStruct = this.type.struct;
174
+ if (!attTypeStruct) {
175
+ return undefined;
176
+ }
177
+
178
+ const types: string[] = [];
179
+
180
+ if (this.isAssignable) {
181
+ types.push(attTypeStruct.name);
182
+ types.push(attTypeStruct.mapperName);
183
+ types.push(attTypeStruct.hclMapperName);
184
+ }
185
+
186
+ if (
187
+ !attTypeStruct.isSingleItem &&
188
+ (attTypeStruct.nestingMode === "list" ||
189
+ attTypeStruct.nestingMode === "set")
190
+ ) {
191
+ types.push(attTypeStruct.listName);
192
+ } else if (attTypeStruct.nestingMode === "map") {
193
+ types.push(attTypeStruct.mapName);
194
+ } else if (attTypeStruct.nestingMode === "maplist") {
195
+ types.push(attTypeStruct.mapListName);
196
+ } else if (attTypeStruct.nestingMode === "mapset") {
197
+ types.push(attTypeStruct.mapListName);
198
+ } else if (attTypeStruct.nestingMode === "listmap") {
199
+ types.push(attTypeStruct.listMapName);
200
+ } else if (attTypeStruct.nestingMode === "setmap") {
201
+ types.push(attTypeStruct.listMapName);
202
+ } else if (
203
+ attTypeStruct.nestingMode === "listlist" ||
204
+ attTypeStruct.nestingMode === "listset" ||
205
+ attTypeStruct.nestingMode === "setlist" ||
206
+ attTypeStruct.nestingMode == "setset"
207
+ ) {
208
+ types.push(attTypeStruct.listListName);
209
+ } else if (!isConfigStruct) {
210
+ types.push(attTypeStruct.outputReferenceName);
211
+ }
212
+ // other types of nested collections aren't supported
213
+
214
+ return types;
215
+ }
216
+ }