@f3liz/rescript-autogen-openapi 0.1.0
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/LICENSE +339 -0
- package/README.md +98 -0
- package/lib/es6/src/Codegen.mjs +423 -0
- package/lib/es6/src/Types.mjs +20 -0
- package/lib/es6/src/core/CodegenUtils.mjs +186 -0
- package/lib/es6/src/core/DocOverride.mjs +399 -0
- package/lib/es6/src/core/FileSystem.mjs +78 -0
- package/lib/es6/src/core/IRBuilder.mjs +201 -0
- package/lib/es6/src/core/OpenAPIParser.mjs +168 -0
- package/lib/es6/src/core/Pipeline.mjs +150 -0
- package/lib/es6/src/core/ReferenceResolver.mjs +41 -0
- package/lib/es6/src/core/Result.mjs +378 -0
- package/lib/es6/src/core/SchemaIR.mjs +355 -0
- package/lib/es6/src/core/SchemaIRParser.mjs +490 -0
- package/lib/es6/src/core/SchemaRefResolver.mjs +146 -0
- package/lib/es6/src/core/SchemaRegistry.mjs +92 -0
- package/lib/es6/src/core/SpecDiffer.mjs +251 -0
- package/lib/es6/src/core/SpecMerger.mjs +237 -0
- package/lib/es6/src/generators/ComponentSchemaGenerator.mjs +125 -0
- package/lib/es6/src/generators/DiffReportGenerator.mjs +155 -0
- package/lib/es6/src/generators/EndpointGenerator.mjs +172 -0
- package/lib/es6/src/generators/IRToSuryGenerator.mjs +233 -0
- package/lib/es6/src/generators/IRToTypeGenerator.mjs +241 -0
- package/lib/es6/src/generators/IRToTypeScriptGenerator.mjs +143 -0
- package/lib/es6/src/generators/ModuleGenerator.mjs +285 -0
- package/lib/es6/src/generators/SchemaCodeGenerator.mjs +77 -0
- package/lib/es6/src/generators/ThinWrapperGenerator.mjs +97 -0
- package/lib/es6/src/generators/TypeScriptDtsGenerator.mjs +172 -0
- package/lib/es6/src/generators/TypeScriptWrapperGenerator.mjs +145 -0
- package/lib/es6/src/types/CodegenError.mjs +79 -0
- package/lib/es6/src/types/Config.mjs +42 -0
- package/lib/es6/src/types/GenerationContext.mjs +24 -0
- package/package.json +44 -0
- package/rescript.json +20 -0
- package/src/Codegen.res +222 -0
- package/src/Types.res +195 -0
- package/src/core/CodegenUtils.res +130 -0
- package/src/core/DocOverride.res +504 -0
- package/src/core/FileSystem.res +62 -0
- package/src/core/IRBuilder.res +66 -0
- package/src/core/OpenAPIParser.res +144 -0
- package/src/core/Pipeline.res +51 -0
- package/src/core/ReferenceResolver.res +41 -0
- package/src/core/Result.res +187 -0
- package/src/core/SchemaIR.res +258 -0
- package/src/core/SchemaIRParser.res +360 -0
- package/src/core/SchemaRefResolver.res +143 -0
- package/src/core/SchemaRegistry.res +107 -0
- package/src/core/SpecDiffer.res +270 -0
- package/src/core/SpecMerger.res +245 -0
- package/src/generators/ComponentSchemaGenerator.res +127 -0
- package/src/generators/DiffReportGenerator.res +152 -0
- package/src/generators/EndpointGenerator.res +172 -0
- package/src/generators/IRToSuryGenerator.res +199 -0
- package/src/generators/IRToTypeGenerator.res +199 -0
- package/src/generators/IRToTypeScriptGenerator.res +72 -0
- package/src/generators/ModuleGenerator.res +362 -0
- package/src/generators/SchemaCodeGenerator.res +83 -0
- package/src/generators/ThinWrapperGenerator.res +124 -0
- package/src/generators/TypeScriptDtsGenerator.res +193 -0
- package/src/generators/TypeScriptWrapperGenerator.res +166 -0
- package/src/types/CodegenError.res +82 -0
- package/src/types/Config.res +89 -0
- package/src/types/GenerationContext.res +23 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as SchemaIR from "../core/SchemaIR.mjs";
|
|
4
|
+
import * as Text from "@std/text";
|
|
5
|
+
import * as CodegenUtils from "../core/CodegenUtils.mjs";
|
|
6
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
7
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
8
|
+
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
9
|
+
import * as GenerationContext from "../types/GenerationContext.mjs";
|
|
10
|
+
import * as IRToSuryGenerator from "./IRToSuryGenerator.mjs";
|
|
11
|
+
import * as ReferenceResolver from "../core/ReferenceResolver.mjs";
|
|
12
|
+
|
|
13
|
+
function generateTypeWithContext(ctx, depthOpt, irType) {
|
|
14
|
+
let depth = depthOpt !== undefined ? depthOpt : 0;
|
|
15
|
+
if (depth > 100) {
|
|
16
|
+
GenerationContext.addWarning(ctx, {
|
|
17
|
+
TAG: "DepthLimitReached",
|
|
18
|
+
depth: depth,
|
|
19
|
+
path: ctx.path
|
|
20
|
+
});
|
|
21
|
+
return "JSON.t";
|
|
22
|
+
}
|
|
23
|
+
let recurse = nextIrType => generateTypeWithContext(ctx, depth + 1 | 0, nextIrType);
|
|
24
|
+
if (typeof irType !== "object") {
|
|
25
|
+
switch (irType) {
|
|
26
|
+
case "Boolean" :
|
|
27
|
+
return "bool";
|
|
28
|
+
case "Null" :
|
|
29
|
+
return "unit";
|
|
30
|
+
case "Unknown" :
|
|
31
|
+
return "JSON.t";
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
switch (irType.TAG) {
|
|
35
|
+
case "String" :
|
|
36
|
+
return "string";
|
|
37
|
+
case "Number" :
|
|
38
|
+
return "float";
|
|
39
|
+
case "Integer" :
|
|
40
|
+
return "int";
|
|
41
|
+
case "Array" :
|
|
42
|
+
return `array<` + recurse(irType.items) + `>`;
|
|
43
|
+
case "Object" :
|
|
44
|
+
let additionalProperties = irType.additionalProperties;
|
|
45
|
+
let properties = irType.properties;
|
|
46
|
+
if (properties.length === 0) {
|
|
47
|
+
if (additionalProperties !== undefined) {
|
|
48
|
+
return `dict<` + recurse(additionalProperties) + `>`;
|
|
49
|
+
} else {
|
|
50
|
+
return "JSON.t";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let fields = properties.map(param => {
|
|
54
|
+
let name = param[0];
|
|
55
|
+
let typeCode = recurse(param[1]);
|
|
56
|
+
let finalType = param[2] ? typeCode : `option<` + typeCode + `>`;
|
|
57
|
+
let camelName = Text.toCamelCase(name);
|
|
58
|
+
let escapedName = CodegenUtils.escapeKeyword(camelName);
|
|
59
|
+
let aliasAnnotation = escapedName !== name ? `@as("` + name + `") ` : "";
|
|
60
|
+
return ` ` + aliasAnnotation + escapedName + `: ` + finalType + `,`;
|
|
61
|
+
}).join("\n");
|
|
62
|
+
return `{\n` + fields + `\n}`;
|
|
63
|
+
case "Literal" :
|
|
64
|
+
let tmp = irType._0;
|
|
65
|
+
if (typeof tmp !== "object") {
|
|
66
|
+
return "unit";
|
|
67
|
+
}
|
|
68
|
+
switch (tmp.TAG) {
|
|
69
|
+
case "StringLiteral" :
|
|
70
|
+
return "string";
|
|
71
|
+
case "NumberLiteral" :
|
|
72
|
+
return "float";
|
|
73
|
+
case "BooleanLiteral" :
|
|
74
|
+
return "bool";
|
|
75
|
+
}
|
|
76
|
+
case "Union" :
|
|
77
|
+
let types = irType._0;
|
|
78
|
+
let match = Stdlib_Array.reduce(types, [
|
|
79
|
+
false,
|
|
80
|
+
false,
|
|
81
|
+
undefined,
|
|
82
|
+
undefined
|
|
83
|
+
], (param, t) => {
|
|
84
|
+
let arrItem = param[2];
|
|
85
|
+
let hArr = param[0];
|
|
86
|
+
if (typeof t !== "object" || t.TAG !== "Array") {
|
|
87
|
+
return [
|
|
88
|
+
hArr,
|
|
89
|
+
true,
|
|
90
|
+
arrItem,
|
|
91
|
+
t
|
|
92
|
+
];
|
|
93
|
+
} else {
|
|
94
|
+
return [
|
|
95
|
+
true,
|
|
96
|
+
param[1],
|
|
97
|
+
t.items,
|
|
98
|
+
param[3]
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
let arrayItemType = match[2];
|
|
103
|
+
if (match[0] && match[1] && SchemaIR.equals(Stdlib_Option.getOr(arrayItemType, "Unknown"), Stdlib_Option.getOr(match[3], "Unknown"))) {
|
|
104
|
+
return `array<` + recurse(Stdlib_Option.getOr(arrayItemType, "Unknown")) + `>`;
|
|
105
|
+
}
|
|
106
|
+
if (types.every(t => {
|
|
107
|
+
if (typeof t !== "object") {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (t.TAG !== "Literal") {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
let tmp = t._0;
|
|
114
|
+
if (typeof tmp !== "object") {
|
|
115
|
+
return false;
|
|
116
|
+
} else {
|
|
117
|
+
return tmp.TAG === "StringLiteral";
|
|
118
|
+
}
|
|
119
|
+
}) && types.length !== 0 && types.length <= 50) {
|
|
120
|
+
let variants = types.map(t => {
|
|
121
|
+
if (typeof t !== "object") {
|
|
122
|
+
return "#Unknown";
|
|
123
|
+
}
|
|
124
|
+
if (t.TAG !== "Literal") {
|
|
125
|
+
return "#Unknown";
|
|
126
|
+
}
|
|
127
|
+
let s = t._0;
|
|
128
|
+
if (typeof s !== "object" || s.TAG !== "StringLiteral") {
|
|
129
|
+
return "#Unknown";
|
|
130
|
+
} else {
|
|
131
|
+
return `#` + Text.toPascalCase(s._0);
|
|
132
|
+
}
|
|
133
|
+
}).join(" | ");
|
|
134
|
+
return `[` + variants + `]`;
|
|
135
|
+
}
|
|
136
|
+
GenerationContext.addWarning(ctx, {
|
|
137
|
+
TAG: "ComplexUnionSimplified",
|
|
138
|
+
location: ctx.path,
|
|
139
|
+
types: types.map(SchemaIR.toString).join(" | ")
|
|
140
|
+
});
|
|
141
|
+
return "JSON.t";
|
|
142
|
+
case "Intersection" :
|
|
143
|
+
let types$1 = irType._0;
|
|
144
|
+
if (types$1.every(t => typeof t !== "object" ? false : t.TAG === "Reference") && types$1.length !== 0) {
|
|
145
|
+
return recurse(Stdlib_Option.getOr(types$1[types$1.length - 1 | 0], "Unknown"));
|
|
146
|
+
} else {
|
|
147
|
+
GenerationContext.addWarning(ctx, {
|
|
148
|
+
TAG: "IntersectionNotFullySupported",
|
|
149
|
+
location: ctx.path,
|
|
150
|
+
note: "Complex intersection"
|
|
151
|
+
});
|
|
152
|
+
return "JSON.t";
|
|
153
|
+
}
|
|
154
|
+
case "Reference" :
|
|
155
|
+
let ref = irType._0;
|
|
156
|
+
let available = ctx.availableSchemas;
|
|
157
|
+
let typePath;
|
|
158
|
+
if (available !== undefined) {
|
|
159
|
+
let name = Stdlib_Option.getOr(ref.split("/")[ref.split("/").length - 1 | 0], "");
|
|
160
|
+
typePath = available.includes(name) ? Text.toPascalCase(name) + `.t` : `ComponentSchemas.` + Text.toPascalCase(name) + `.t`;
|
|
161
|
+
} else {
|
|
162
|
+
typePath = Stdlib_Option.getOr(ReferenceResolver.refToTypePath(ctx.insideComponentSchemas, ctx.modulePrefix, ref), "JSON.t");
|
|
163
|
+
}
|
|
164
|
+
if (typePath === "JSON.t") {
|
|
165
|
+
GenerationContext.addWarning(ctx, {
|
|
166
|
+
TAG: "FallbackToJson",
|
|
167
|
+
reason: `Unresolved ref: ` + ref,
|
|
168
|
+
context: {
|
|
169
|
+
path: ctx.path,
|
|
170
|
+
operation: "gen ref",
|
|
171
|
+
schema: undefined
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return typePath;
|
|
176
|
+
case "Option" :
|
|
177
|
+
return `option<` + recurse(irType._0) + `>`;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function generateType(depthOpt, pathOpt, insideComponentSchemasOpt, availableSchemas, modulePrefixOpt, irType) {
|
|
183
|
+
let depth = depthOpt !== undefined ? depthOpt : 0;
|
|
184
|
+
let path = pathOpt !== undefined ? pathOpt : "";
|
|
185
|
+
let insideComponentSchemas = insideComponentSchemasOpt !== undefined ? insideComponentSchemasOpt : false;
|
|
186
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
187
|
+
let ctx = GenerationContext.make(path, insideComponentSchemas, availableSchemas, modulePrefix, undefined);
|
|
188
|
+
return [
|
|
189
|
+
generateTypeWithContext(ctx, depth, irType),
|
|
190
|
+
ctx.warnings
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function generateNamedType(namedSchema, insideComponentSchemasOpt, availableSchemas, modulePrefixOpt) {
|
|
195
|
+
let insideComponentSchemas = insideComponentSchemasOpt !== undefined ? insideComponentSchemasOpt : false;
|
|
196
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
197
|
+
let ctx = GenerationContext.make(`type.` + namedSchema.name, insideComponentSchemas, availableSchemas, modulePrefix, undefined);
|
|
198
|
+
let d = namedSchema.description;
|
|
199
|
+
let doc = d !== undefined ? CodegenUtils.generateDocString(undefined, d, undefined) : "";
|
|
200
|
+
return [
|
|
201
|
+
doc + `type ` + namedSchema.name + ` = ` + generateTypeWithContext(ctx, 0, namedSchema.type_),
|
|
202
|
+
ctx.warnings
|
|
203
|
+
];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function generateAllTypes(context) {
|
|
207
|
+
let warnings = [];
|
|
208
|
+
let types = Object.values(context.schemas).toSorted((a, b) => Primitive_string.compare(a.name, b.name)).map(s => {
|
|
209
|
+
let match = generateNamedType(s, undefined, undefined, undefined);
|
|
210
|
+
warnings.push(...match[1]);
|
|
211
|
+
return match[0];
|
|
212
|
+
});
|
|
213
|
+
return [
|
|
214
|
+
types,
|
|
215
|
+
warnings
|
|
216
|
+
];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function generateTypeAndSchema(namedSchema) {
|
|
220
|
+
let match = generateNamedType(namedSchema, undefined, undefined, undefined);
|
|
221
|
+
let match$1 = IRToSuryGenerator.generateNamedSchema(namedSchema, undefined, undefined, undefined);
|
|
222
|
+
return [
|
|
223
|
+
[
|
|
224
|
+
match[0],
|
|
225
|
+
match$1[0]
|
|
226
|
+
],
|
|
227
|
+
match[1].concat(match$1[1])
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
let addWarning = GenerationContext.addWarning;
|
|
232
|
+
|
|
233
|
+
export {
|
|
234
|
+
addWarning,
|
|
235
|
+
generateTypeWithContext,
|
|
236
|
+
generateType,
|
|
237
|
+
generateNamedType,
|
|
238
|
+
generateAllTypes,
|
|
239
|
+
generateTypeAndSchema,
|
|
240
|
+
}
|
|
241
|
+
/* @std/text Not a pure module */
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Text from "@std/text";
|
|
4
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
+
import * as SchemaIRParser from "../core/SchemaIRParser.mjs";
|
|
6
|
+
|
|
7
|
+
function generateType(_irType, _isOptionalOpt) {
|
|
8
|
+
while (true) {
|
|
9
|
+
let isOptionalOpt = _isOptionalOpt;
|
|
10
|
+
let irType = _irType;
|
|
11
|
+
let isOptional = isOptionalOpt !== undefined ? isOptionalOpt : false;
|
|
12
|
+
if (typeof irType !== "object") {
|
|
13
|
+
switch (irType) {
|
|
14
|
+
case "Boolean" :
|
|
15
|
+
return "boolean";
|
|
16
|
+
case "Null" :
|
|
17
|
+
return "null";
|
|
18
|
+
case "Unknown" :
|
|
19
|
+
return "unknown";
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
switch (irType.TAG) {
|
|
23
|
+
case "String" :
|
|
24
|
+
return "string";
|
|
25
|
+
case "Number" :
|
|
26
|
+
case "Integer" :
|
|
27
|
+
return "number";
|
|
28
|
+
case "Array" :
|
|
29
|
+
return generateType(irType.items, undefined) + `[]`;
|
|
30
|
+
case "Object" :
|
|
31
|
+
return generateObjectType(irType.properties, irType.additionalProperties);
|
|
32
|
+
case "Literal" :
|
|
33
|
+
let literal = irType._0;
|
|
34
|
+
if (typeof literal !== "object") {
|
|
35
|
+
return "null";
|
|
36
|
+
}
|
|
37
|
+
switch (literal.TAG) {
|
|
38
|
+
case "StringLiteral" :
|
|
39
|
+
return `"` + literal._0 + `"`;
|
|
40
|
+
case "NumberLiteral" :
|
|
41
|
+
return literal._0.toString();
|
|
42
|
+
case "BooleanLiteral" :
|
|
43
|
+
if (literal._0) {
|
|
44
|
+
return "true";
|
|
45
|
+
} else {
|
|
46
|
+
return "false";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
case "Union" :
|
|
50
|
+
return irType._0.map(t => generateType(t, undefined)).join(" | ");
|
|
51
|
+
case "Intersection" :
|
|
52
|
+
return irType._0.map(t => generateType(t, undefined)).join(" & ");
|
|
53
|
+
case "Reference" :
|
|
54
|
+
let ref = irType._0;
|
|
55
|
+
let match = ref.split("/");
|
|
56
|
+
if (match.length !== 4) {
|
|
57
|
+
return ref;
|
|
58
|
+
}
|
|
59
|
+
let match$1 = match[1];
|
|
60
|
+
if (match$1 !== "components") {
|
|
61
|
+
return ref;
|
|
62
|
+
}
|
|
63
|
+
let match$2 = match[2];
|
|
64
|
+
if (match$2 !== "schemas") {
|
|
65
|
+
return ref;
|
|
66
|
+
}
|
|
67
|
+
let name = match[3];
|
|
68
|
+
return `ComponentSchemas.` + name;
|
|
69
|
+
case "Option" :
|
|
70
|
+
let inner = irType._0;
|
|
71
|
+
if (!isOptional) {
|
|
72
|
+
return generateType(inner, undefined) + ` | undefined`;
|
|
73
|
+
}
|
|
74
|
+
_isOptionalOpt = true;
|
|
75
|
+
_irType = inner;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function generateObjectType(properties, additionalProperties) {
|
|
83
|
+
let propertyLines = properties.map(param => {
|
|
84
|
+
let isRequired = param[2];
|
|
85
|
+
let fieldType = param[1];
|
|
86
|
+
let match;
|
|
87
|
+
match = typeof fieldType !== "object" ? [
|
|
88
|
+
fieldType,
|
|
89
|
+
!isRequired
|
|
90
|
+
] : (
|
|
91
|
+
fieldType.TAG === "Option" ? [
|
|
92
|
+
fieldType._0,
|
|
93
|
+
true
|
|
94
|
+
] : [
|
|
95
|
+
fieldType,
|
|
96
|
+
!isRequired
|
|
97
|
+
]
|
|
98
|
+
);
|
|
99
|
+
return ` ` + param[0] + (
|
|
100
|
+
match[1] ? "?" : ""
|
|
101
|
+
) + `: ` + generateType(match[0], true) + `;`;
|
|
102
|
+
});
|
|
103
|
+
let additionalPropertiesLines = Stdlib_Option.mapOr(additionalProperties, [], valueType => [` [key: string]: ` + generateType(valueType, undefined) + `;`]);
|
|
104
|
+
let allLines = propertyLines.concat(additionalPropertiesLines);
|
|
105
|
+
if (allLines.length === 0) {
|
|
106
|
+
return "Record<string, never>";
|
|
107
|
+
} else {
|
|
108
|
+
return `{\n` + allLines.join("\n") + `\n}`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function generateNamedType(namedSchema) {
|
|
113
|
+
let docComment = Stdlib_Option.mapOr(namedSchema.description, "", description => `/** ` + description + ` */\n`);
|
|
114
|
+
let typeCode = generateType(namedSchema.type_, undefined);
|
|
115
|
+
let match = namedSchema.type_;
|
|
116
|
+
let declaration;
|
|
117
|
+
let exit = 0;
|
|
118
|
+
if (typeof match !== "object" || match.TAG !== "Object") {
|
|
119
|
+
exit = 1;
|
|
120
|
+
} else {
|
|
121
|
+
declaration = `export interface ` + namedSchema.name + ` ` + typeCode;
|
|
122
|
+
}
|
|
123
|
+
if (exit === 1) {
|
|
124
|
+
declaration = `export type ` + namedSchema.name + ` = ` + typeCode + `;`;
|
|
125
|
+
}
|
|
126
|
+
return docComment + declaration;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function generateParameterType(name, schema) {
|
|
130
|
+
let match = SchemaIRParser.parseJsonSchema(undefined, schema);
|
|
131
|
+
return [
|
|
132
|
+
Text.toCamelCase(name),
|
|
133
|
+
generateType(match[0], undefined)
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export {
|
|
138
|
+
generateType,
|
|
139
|
+
generateObjectType,
|
|
140
|
+
generateNamedType,
|
|
141
|
+
generateParameterType,
|
|
142
|
+
}
|
|
143
|
+
/* @std/text Not a pure module */
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Pipeline from "../core/Pipeline.mjs";
|
|
4
|
+
import * as Text from "@std/text";
|
|
5
|
+
import * as Belt_Array from "@rescript/runtime/lib/es6/Belt_Array.js";
|
|
6
|
+
import * as FileSystem from "../core/FileSystem.mjs";
|
|
7
|
+
import * as CodegenUtils from "../core/CodegenUtils.mjs";
|
|
8
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
9
|
+
import * as OpenAPIParser from "../core/OpenAPIParser.mjs";
|
|
10
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
11
|
+
import * as SchemaIRParser from "../core/SchemaIRParser.mjs";
|
|
12
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
13
|
+
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
14
|
+
import * as EndpointGenerator from "./EndpointGenerator.mjs";
|
|
15
|
+
import * as IRToSuryGenerator from "./IRToSuryGenerator.mjs";
|
|
16
|
+
import * as IRToTypeGenerator from "./IRToTypeGenerator.mjs";
|
|
17
|
+
import * as ComponentSchemaGenerator from "./ComponentSchemaGenerator.mjs";
|
|
18
|
+
|
|
19
|
+
function generateSchemaCodeForDict(schemaDict) {
|
|
20
|
+
return Object.entries(schemaDict).toSorted((param, param$1) => Primitive_string.compare(param[0], param$1[0])).flatMap(param => {
|
|
21
|
+
let schema = param[1];
|
|
22
|
+
let name = param[0];
|
|
23
|
+
let match = SchemaIRParser.parseJsonSchema(undefined, schema);
|
|
24
|
+
let ir = match[0];
|
|
25
|
+
let match$1 = IRToTypeGenerator.generateNamedType({
|
|
26
|
+
name: name,
|
|
27
|
+
description: schema.description,
|
|
28
|
+
type_: ir
|
|
29
|
+
}, undefined, undefined, undefined);
|
|
30
|
+
let match$2 = IRToSuryGenerator.generateNamedSchema({
|
|
31
|
+
name: name + `Schema`,
|
|
32
|
+
description: schema.description,
|
|
33
|
+
type_: ir
|
|
34
|
+
}, undefined, undefined, undefined);
|
|
35
|
+
return [
|
|
36
|
+
CodegenUtils.indent(match$1[0], 2),
|
|
37
|
+
CodegenUtils.indent(match$2[0], 2),
|
|
38
|
+
""
|
|
39
|
+
];
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function generateTagModulesCode(endpoints, overrideDir, indentOpt) {
|
|
44
|
+
let indent = indentOpt !== undefined ? indentOpt : 2;
|
|
45
|
+
let groupedByTag = OpenAPIParser.groupByTag(endpoints);
|
|
46
|
+
let indentStr = " ".repeat(indent);
|
|
47
|
+
return Stdlib_Array.filterMap(Object.keys(groupedByTag).toSorted(Primitive_string.compare), tag => Stdlib_Option.map(groupedByTag[tag], tagEndpoints => {
|
|
48
|
+
let moduleName = Text.toPascalCase(tag);
|
|
49
|
+
let endpointLines = tagEndpoints.flatMap(endpoint => [
|
|
50
|
+
CodegenUtils.indent(EndpointGenerator.generateEndpointCode(endpoint, overrideDir, moduleName, undefined), indent + 2 | 0),
|
|
51
|
+
""
|
|
52
|
+
]);
|
|
53
|
+
return [indentStr + `module ` + moduleName + ` = {`].concat(endpointLines.concat([
|
|
54
|
+
indentStr + `}`,
|
|
55
|
+
""
|
|
56
|
+
]));
|
|
57
|
+
})).flatMap(lines => lines);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function generateTagModuleFile(tag, endpoints, $staropt$star, $staropt$star$1, overrideDir) {
|
|
61
|
+
if ($staropt$star === undefined) {
|
|
62
|
+
true;
|
|
63
|
+
}
|
|
64
|
+
let wrapInModule = $staropt$star$1 !== undefined ? $staropt$star$1 : false;
|
|
65
|
+
let moduleName = Text.toPascalCase(tag);
|
|
66
|
+
let header = CodegenUtils.generateFileHeader(`API endpoints for ` + tag);
|
|
67
|
+
let body = endpoints.map(endpoint => EndpointGenerator.generateEndpointCode(endpoint, overrideDir, moduleName, undefined)).join("\n\n");
|
|
68
|
+
if (wrapInModule) {
|
|
69
|
+
return CodegenUtils.trimMargin(`
|
|
70
|
+
|` + header.trimEnd() + `
|
|
71
|
+
|
|
|
72
|
+
|module ` + moduleName + ` = {
|
|
73
|
+
|` + CodegenUtils.indent(body, 2) + `
|
|
74
|
+
|}
|
|
75
|
+
|`, undefined);
|
|
76
|
+
} else {
|
|
77
|
+
return CodegenUtils.trimMargin(`
|
|
78
|
+
|` + header.trimEnd() + `
|
|
79
|
+
|
|
|
80
|
+
|` + body + `
|
|
81
|
+
|`, undefined);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function generateAllTagModules(endpoints, includeSchemasOpt, wrapInModuleOpt, overrideDir) {
|
|
86
|
+
let includeSchemas = includeSchemasOpt !== undefined ? includeSchemasOpt : true;
|
|
87
|
+
let wrapInModule = wrapInModuleOpt !== undefined ? wrapInModuleOpt : false;
|
|
88
|
+
let groupedByTag = OpenAPIParser.groupByTag(endpoints);
|
|
89
|
+
return Object.entries(groupedByTag).toSorted((param, param$1) => Primitive_string.compare(param[0], param$1[0])).map(param => {
|
|
90
|
+
let tag = param[0];
|
|
91
|
+
return [
|
|
92
|
+
tag,
|
|
93
|
+
generateTagModuleFile(tag, param[1], includeSchemas, wrapInModule, overrideDir)
|
|
94
|
+
];
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function generateIndexModule(tags, moduleNameOpt) {
|
|
99
|
+
let moduleName = moduleNameOpt !== undefined ? moduleNameOpt : "API";
|
|
100
|
+
let header = CodegenUtils.generateFileHeader("Main API module index");
|
|
101
|
+
let modules = tags.toSorted(Primitive_string.compare).map(tag => {
|
|
102
|
+
let m = Text.toPascalCase(tag);
|
|
103
|
+
return ` module ` + m + ` = ` + m;
|
|
104
|
+
}).join("\n");
|
|
105
|
+
return CodegenUtils.trimMargin(`
|
|
106
|
+
|` + header.trimEnd() + `
|
|
107
|
+
|
|
|
108
|
+
|module ` + moduleName + ` = {
|
|
109
|
+
|` + modules + `
|
|
110
|
+
|}
|
|
111
|
+
|`, undefined);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function generateFlatModuleCode(moduleName, endpoints, overrideDir) {
|
|
115
|
+
let header = CodegenUtils.generateFileHeader(`All API endpoints in ` + moduleName);
|
|
116
|
+
let body = endpoints.map(endpoint => CodegenUtils.indent(EndpointGenerator.generateEndpointCode(endpoint, overrideDir, moduleName, undefined), 2)).join("\n\n");
|
|
117
|
+
return CodegenUtils.trimMargin(`
|
|
118
|
+
|` + header.trimEnd() + `
|
|
119
|
+
|
|
|
120
|
+
|module ` + moduleName + ` = {
|
|
121
|
+
|` + body + `
|
|
122
|
+
|}
|
|
123
|
+
|`, undefined);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function internalGenerateIntegratedModule(name, description, endpoints, schemas, overrideDir, isExtensionOpt, includeHeaderOpt) {
|
|
127
|
+
let isExtension = isExtensionOpt !== undefined ? isExtensionOpt : false;
|
|
128
|
+
let includeHeader = includeHeaderOpt !== undefined ? includeHeaderOpt : true;
|
|
129
|
+
let lines = [];
|
|
130
|
+
if (includeHeader) {
|
|
131
|
+
lines.push(CodegenUtils.generateFileHeader(description), "");
|
|
132
|
+
}
|
|
133
|
+
lines.push(`module ` + name + ` = {`);
|
|
134
|
+
Stdlib_Option.forEach(schemas, schemaDict => {
|
|
135
|
+
if (Object.keys(schemaDict).length !== 0) {
|
|
136
|
+
lines.push(...Belt_Array.concatMany([
|
|
137
|
+
[
|
|
138
|
+
` // ` + (
|
|
139
|
+
isExtension ? "Extension" : "Component"
|
|
140
|
+
) + ` Schemas`,
|
|
141
|
+
""
|
|
142
|
+
],
|
|
143
|
+
generateSchemaCodeForDict(schemaDict)
|
|
144
|
+
]));
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
if (endpoints.length !== 0) {
|
|
149
|
+
if (isExtension) {
|
|
150
|
+
lines.push(" // Extension Endpoints", "");
|
|
151
|
+
}
|
|
152
|
+
lines.push(...generateTagModulesCode(endpoints, overrideDir, undefined));
|
|
153
|
+
}
|
|
154
|
+
lines.push("}");
|
|
155
|
+
return lines.join("\n");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function generateSharedModule(endpoints, schemas, overrideDir, includeHeaderOpt) {
|
|
159
|
+
let includeHeader = includeHeaderOpt !== undefined ? includeHeaderOpt : true;
|
|
160
|
+
return internalGenerateIntegratedModule("Shared", "Shared API code", endpoints, schemas, overrideDir, undefined, includeHeader);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function generateExtensionModule(forkName, endpoints, schemas, overrideDir, includeHeaderOpt) {
|
|
164
|
+
let includeHeader = includeHeaderOpt !== undefined ? includeHeaderOpt : true;
|
|
165
|
+
return internalGenerateIntegratedModule(Text.toPascalCase(forkName) + `Extensions`, forkName + ` extensions`, endpoints, schemas, overrideDir, true, includeHeader);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function generateCombinedModule(forkName, sharedEndpoints, extensionEndpoints, sharedSchemas, extensionSchemas, overrideDir) {
|
|
169
|
+
let header = CodegenUtils.generateFileHeader(`Combined Shared and ` + forkName + ` extensions`);
|
|
170
|
+
let shared = generateSharedModule(sharedEndpoints, sharedSchemas, overrideDir, false);
|
|
171
|
+
let extension = generateExtensionModule(forkName, extensionEndpoints, extensionSchemas, overrideDir, false);
|
|
172
|
+
return CodegenUtils.trimMargin(`
|
|
173
|
+
|` + header.trimEnd() + `
|
|
174
|
+
|
|
|
175
|
+
|` + shared + `
|
|
176
|
+
|
|
|
177
|
+
|` + extension + `
|
|
178
|
+
|`, undefined);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function generateTagModuleFiles(endpoints, outputDir, wrapInModuleOpt, overrideDir) {
|
|
182
|
+
let wrapInModule = wrapInModuleOpt !== undefined ? wrapInModuleOpt : false;
|
|
183
|
+
let files = generateAllTagModules(endpoints, true, wrapInModule, overrideDir).map(param => {
|
|
184
|
+
let path = FileSystem.makePath(outputDir, Text.toPascalCase(param[0]) + `.res`);
|
|
185
|
+
return {
|
|
186
|
+
path: path,
|
|
187
|
+
content: param[1]
|
|
188
|
+
};
|
|
189
|
+
});
|
|
190
|
+
return Pipeline.fromFilesAndWarnings(files, []);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function generateFlatModuleFile(moduleName, endpoints, outputDir, overrideDir) {
|
|
194
|
+
let path = FileSystem.makePath(outputDir, moduleName + `.res`);
|
|
195
|
+
let content = generateFlatModuleCode(moduleName, endpoints, overrideDir);
|
|
196
|
+
return Pipeline.fromFile({
|
|
197
|
+
path: path,
|
|
198
|
+
content: content
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function generateInstanceTagModules(instanceName, modulePrefix, endpoints, schemas, outputDir, overrideDir) {
|
|
203
|
+
let apiDir = FileSystem.makePath(FileSystem.makePath(outputDir, instanceName), "api");
|
|
204
|
+
let schemaFiles = Stdlib_Option.mapOr(schemas, [], schemaDict => {
|
|
205
|
+
if (Object.keys(schemaDict).length === 0) {
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
let result = ComponentSchemaGenerator.generate({
|
|
209
|
+
openapi: "3.1.0",
|
|
210
|
+
info: {
|
|
211
|
+
title: instanceName,
|
|
212
|
+
version: "1.0.0",
|
|
213
|
+
description: undefined
|
|
214
|
+
},
|
|
215
|
+
paths: {},
|
|
216
|
+
components: {
|
|
217
|
+
schemas: schemaDict
|
|
218
|
+
}
|
|
219
|
+
}, apiDir);
|
|
220
|
+
return result.files.map(file => {
|
|
221
|
+
if (file.path.endsWith("ComponentSchemas.res")) {
|
|
222
|
+
return {
|
|
223
|
+
path: file.path.replace("ComponentSchemas.res", modulePrefix + `ComponentSchemas.res`),
|
|
224
|
+
content: file.content
|
|
225
|
+
};
|
|
226
|
+
} else {
|
|
227
|
+
return file;
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
let groupedByTag = OpenAPIParser.groupByTag(endpoints);
|
|
232
|
+
let endpointFiles = Stdlib_Array.filterMap(Object.entries(groupedByTag).toSorted((param, param$1) => Primitive_string.compare(param[0], param$1[0])), param => {
|
|
233
|
+
let tag = param[0];
|
|
234
|
+
let moduleName = modulePrefix + Text.toPascalCase(tag);
|
|
235
|
+
let endpointCodes = param[1].flatMap(endpoint => [
|
|
236
|
+
EndpointGenerator.generateEndpointCode(endpoint, overrideDir, moduleName, modulePrefix),
|
|
237
|
+
""
|
|
238
|
+
]);
|
|
239
|
+
let content = Belt_Array.concatMany([
|
|
240
|
+
[
|
|
241
|
+
CodegenUtils.generateFileHeader(instanceName + ` API for ` + tag),
|
|
242
|
+
""
|
|
243
|
+
],
|
|
244
|
+
endpointCodes
|
|
245
|
+
]).join("\n");
|
|
246
|
+
let path = FileSystem.makePath(apiDir, moduleName + `.res`);
|
|
247
|
+
return {
|
|
248
|
+
path: path,
|
|
249
|
+
content: content
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
return Pipeline.fromFilesAndWarnings(schemaFiles.concat(endpointFiles), []);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
let generateBaseTagModules = generateInstanceTagModules;
|
|
256
|
+
|
|
257
|
+
let generateForkTagModules = generateInstanceTagModules;
|
|
258
|
+
|
|
259
|
+
function generateSeparatePerTagModules(baseName, basePrefix, forkName, forkPrefixOpt, sharedEndpoints, extensionEndpoints, sharedSchemas, extensionSchemas, outputDir, overrideDir) {
|
|
260
|
+
let forkPrefix = forkPrefixOpt !== undefined ? Primitive_option.valFromOption(forkPrefixOpt) : undefined;
|
|
261
|
+
return Pipeline.combine([
|
|
262
|
+
generateBaseTagModules(baseName, basePrefix, sharedEndpoints, sharedSchemas, outputDir, overrideDir),
|
|
263
|
+
generateForkTagModules(forkName, Stdlib_Option.getOr(forkPrefix, Text.toPascalCase(forkName)), extensionEndpoints, extensionSchemas, outputDir, overrideDir)
|
|
264
|
+
]);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export {
|
|
268
|
+
generateSchemaCodeForDict,
|
|
269
|
+
generateTagModulesCode,
|
|
270
|
+
generateTagModuleFile,
|
|
271
|
+
generateAllTagModules,
|
|
272
|
+
generateIndexModule,
|
|
273
|
+
generateFlatModuleCode,
|
|
274
|
+
internalGenerateIntegratedModule,
|
|
275
|
+
generateSharedModule,
|
|
276
|
+
generateExtensionModule,
|
|
277
|
+
generateCombinedModule,
|
|
278
|
+
generateTagModuleFiles,
|
|
279
|
+
generateFlatModuleFile,
|
|
280
|
+
generateInstanceTagModules,
|
|
281
|
+
generateBaseTagModules,
|
|
282
|
+
generateForkTagModules,
|
|
283
|
+
generateSeparatePerTagModules,
|
|
284
|
+
}
|
|
285
|
+
/* @std/text Not a pure module */
|