@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.
- package/.spec.swcrc +22 -0
- package/LICENSE +355 -0
- package/README.md +1 -1
- package/build/__tests__/edge-provider-schema/cli.js +8 -3
- package/build/get/__tests__/generator/import-style.test.d.ts +2 -0
- package/build/get/__tests__/generator/import-style.test.js +101 -0
- package/build/get/__tests__/generator/module-generator.test.js +12 -12
- package/build/get/constructs-maker.d.ts +5 -1
- package/build/get/constructs-maker.js +14 -6
- package/build/get/generator/emitter/struct-emitter.d.ts +2 -1
- package/build/get/generator/emitter/struct-emitter.js +14 -11
- package/build/get/generator/module-generator.js +3 -3
- package/build/get/generator/provider-generator.d.ts +9 -1
- package/build/get/generator/provider-generator.js +9 -6
- package/jest.config.js +16 -9
- package/package.json +24 -23
- package/package.sh +1 -1
- package/src/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +8 -8
- package/src/__tests__/__snapshots__/provider.test.ts.snap +2951 -2951
- package/src/__tests__/edge-provider-schema/builder.ts +185 -0
- package/src/__tests__/edge-provider-schema/cli.ts +51 -0
- package/src/__tests__/edge-provider-schema/index.ts +161 -0
- package/src/__tests__/edge-provider-schema.test.ts +24 -0
- package/src/__tests__/provider.test.ts +180 -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__/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.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 +65 -65
- 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/export-sharding.test.ts +169 -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.test.ts +51 -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/types.test.ts +611 -0
- package/src/get/__tests__/generator/versions-file.test.ts +72 -0
- package/src/get/__tests__/util.ts +75 -0
- package/src/get/constructs-maker.ts +822 -0
- package/src/get/generator/custom-defaults.ts +493 -0
- package/src/get/generator/emitter/attributes-emitter.ts +225 -0
- package/src/get/generator/emitter/index.ts +5 -0
- package/src/get/generator/emitter/resource-emitter.ts +226 -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 +216 -0
- package/src/get/generator/models/attribute-type-model.ts +448 -0
- package/src/get/generator/models/index.ts +7 -0
- package/src/get/generator/models/resource-model.ts +161 -0
- package/src/get/generator/models/scope.ts +54 -0
- package/src/get/generator/models/struct.ts +116 -0
- package/src/get/generator/module-generator.ts +234 -0
- package/src/get/generator/provider-generator.ts +355 -0
- package/src/get/generator/resource-parser.ts +762 -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
|
@@ -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
|
+
}
|