@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.
Files changed (64) hide show
  1. package/LICENSE +339 -0
  2. package/README.md +98 -0
  3. package/lib/es6/src/Codegen.mjs +423 -0
  4. package/lib/es6/src/Types.mjs +20 -0
  5. package/lib/es6/src/core/CodegenUtils.mjs +186 -0
  6. package/lib/es6/src/core/DocOverride.mjs +399 -0
  7. package/lib/es6/src/core/FileSystem.mjs +78 -0
  8. package/lib/es6/src/core/IRBuilder.mjs +201 -0
  9. package/lib/es6/src/core/OpenAPIParser.mjs +168 -0
  10. package/lib/es6/src/core/Pipeline.mjs +150 -0
  11. package/lib/es6/src/core/ReferenceResolver.mjs +41 -0
  12. package/lib/es6/src/core/Result.mjs +378 -0
  13. package/lib/es6/src/core/SchemaIR.mjs +355 -0
  14. package/lib/es6/src/core/SchemaIRParser.mjs +490 -0
  15. package/lib/es6/src/core/SchemaRefResolver.mjs +146 -0
  16. package/lib/es6/src/core/SchemaRegistry.mjs +92 -0
  17. package/lib/es6/src/core/SpecDiffer.mjs +251 -0
  18. package/lib/es6/src/core/SpecMerger.mjs +237 -0
  19. package/lib/es6/src/generators/ComponentSchemaGenerator.mjs +125 -0
  20. package/lib/es6/src/generators/DiffReportGenerator.mjs +155 -0
  21. package/lib/es6/src/generators/EndpointGenerator.mjs +172 -0
  22. package/lib/es6/src/generators/IRToSuryGenerator.mjs +233 -0
  23. package/lib/es6/src/generators/IRToTypeGenerator.mjs +241 -0
  24. package/lib/es6/src/generators/IRToTypeScriptGenerator.mjs +143 -0
  25. package/lib/es6/src/generators/ModuleGenerator.mjs +285 -0
  26. package/lib/es6/src/generators/SchemaCodeGenerator.mjs +77 -0
  27. package/lib/es6/src/generators/ThinWrapperGenerator.mjs +97 -0
  28. package/lib/es6/src/generators/TypeScriptDtsGenerator.mjs +172 -0
  29. package/lib/es6/src/generators/TypeScriptWrapperGenerator.mjs +145 -0
  30. package/lib/es6/src/types/CodegenError.mjs +79 -0
  31. package/lib/es6/src/types/Config.mjs +42 -0
  32. package/lib/es6/src/types/GenerationContext.mjs +24 -0
  33. package/package.json +44 -0
  34. package/rescript.json +20 -0
  35. package/src/Codegen.res +222 -0
  36. package/src/Types.res +195 -0
  37. package/src/core/CodegenUtils.res +130 -0
  38. package/src/core/DocOverride.res +504 -0
  39. package/src/core/FileSystem.res +62 -0
  40. package/src/core/IRBuilder.res +66 -0
  41. package/src/core/OpenAPIParser.res +144 -0
  42. package/src/core/Pipeline.res +51 -0
  43. package/src/core/ReferenceResolver.res +41 -0
  44. package/src/core/Result.res +187 -0
  45. package/src/core/SchemaIR.res +258 -0
  46. package/src/core/SchemaIRParser.res +360 -0
  47. package/src/core/SchemaRefResolver.res +143 -0
  48. package/src/core/SchemaRegistry.res +107 -0
  49. package/src/core/SpecDiffer.res +270 -0
  50. package/src/core/SpecMerger.res +245 -0
  51. package/src/generators/ComponentSchemaGenerator.res +127 -0
  52. package/src/generators/DiffReportGenerator.res +152 -0
  53. package/src/generators/EndpointGenerator.res +172 -0
  54. package/src/generators/IRToSuryGenerator.res +199 -0
  55. package/src/generators/IRToTypeGenerator.res +199 -0
  56. package/src/generators/IRToTypeScriptGenerator.res +72 -0
  57. package/src/generators/ModuleGenerator.res +362 -0
  58. package/src/generators/SchemaCodeGenerator.res +83 -0
  59. package/src/generators/ThinWrapperGenerator.res +124 -0
  60. package/src/generators/TypeScriptDtsGenerator.res +193 -0
  61. package/src/generators/TypeScriptWrapperGenerator.res +166 -0
  62. package/src/types/CodegenError.res +82 -0
  63. package/src/types/Config.res +89 -0
  64. 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 */