@f3liz/rescript-autogen-openapi 0.3.1
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 +373 -0
- package/README.md +111 -0
- package/lib/es6/src/Codegen.d.ts +28 -0
- package/lib/es6/src/Codegen.mjs +423 -0
- package/lib/es6/src/Types.d.ts +286 -0
- package/lib/es6/src/Types.mjs +20 -0
- package/lib/es6/src/bindings/Toposort.mjs +12 -0
- package/lib/es6/src/core/CodegenUtils.mjs +261 -0
- package/lib/es6/src/core/DocOverride.mjs +399 -0
- package/lib/es6/src/core/FileSystem.d.ts +4 -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.d.ts +6 -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 +425 -0
- package/lib/es6/src/core/SchemaIRParser.mjs +683 -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 +207 -0
- package/lib/es6/src/generators/DiffReportGenerator.mjs +155 -0
- package/lib/es6/src/generators/EndpointGenerator.mjs +173 -0
- package/lib/es6/src/generators/IRToSuryGenerator.mjs +543 -0
- package/lib/es6/src/generators/IRToTypeGenerator.mjs +592 -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.d.ts +66 -0
- package/lib/es6/src/types/CodegenError.mjs +79 -0
- package/lib/es6/src/types/Config.d.ts +31 -0
- package/lib/es6/src/types/Config.mjs +42 -0
- package/lib/es6/src/types/GenerationContext.mjs +47 -0
- package/package.json +53 -0
- package/rescript.json +26 -0
- package/src/Codegen.res +231 -0
- package/src/Types.res +222 -0
- package/src/bindings/Toposort.res +16 -0
- package/src/core/CodegenUtils.res +180 -0
- package/src/core/DocOverride.res +504 -0
- package/src/core/FileSystem.res +63 -0
- package/src/core/IRBuilder.res +66 -0
- package/src/core/OpenAPIParser.res +144 -0
- package/src/core/Pipeline.res +52 -0
- package/src/core/ReferenceResolver.res +41 -0
- package/src/core/Result.res +187 -0
- package/src/core/SchemaIR.res +291 -0
- package/src/core/SchemaIRParser.res +454 -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 +210 -0
- package/src/generators/DiffReportGenerator.res +152 -0
- package/src/generators/EndpointGenerator.res +176 -0
- package/src/generators/IRToSuryGenerator.res +386 -0
- package/src/generators/IRToTypeGenerator.res +423 -0
- package/src/generators/IRToTypeScriptGenerator.res +77 -0
- package/src/generators/ModuleGenerator.res +363 -0
- package/src/generators/SchemaCodeGenerator.res +84 -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 +85 -0
- package/src/types/Config.res +95 -0
- package/src/types/GenerationContext.res +56 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as DocOverride from "../core/DocOverride.mjs";
|
|
4
|
+
import * as CodegenUtils from "../core/CodegenUtils.mjs";
|
|
5
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
import * as SchemaIRParser from "../core/SchemaIRParser.mjs";
|
|
8
|
+
import * as JsConvertCase from "js-convert-case";
|
|
9
|
+
import * as IRToSuryGenerator from "./IRToSuryGenerator.mjs";
|
|
10
|
+
import * as IRToTypeGenerator from "./IRToTypeGenerator.mjs";
|
|
11
|
+
|
|
12
|
+
function getJsonSchemaFromRequestBody(requestBody) {
|
|
13
|
+
return Stdlib_Option.flatMap(requestBody, body => Stdlib_Option.flatMap(Object.entries(body.content)[0], param => param[1].schema));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function generateTypeCodeAndSchemaCode(jsonSchema, typeName, schemaName, modulePrefixOpt) {
|
|
17
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
18
|
+
let match = SchemaIRParser.parseJsonSchema(undefined, jsonSchema);
|
|
19
|
+
let ir = match[0];
|
|
20
|
+
let match$1 = IRToTypeGenerator.generateNamedType({
|
|
21
|
+
name: typeName,
|
|
22
|
+
description: jsonSchema.description,
|
|
23
|
+
type_: ir
|
|
24
|
+
}, undefined, undefined, modulePrefix);
|
|
25
|
+
let match$2 = IRToSuryGenerator.generateNamedSchema({
|
|
26
|
+
name: schemaName,
|
|
27
|
+
description: jsonSchema.description,
|
|
28
|
+
type_: ir
|
|
29
|
+
}, undefined, undefined, modulePrefix, match$1[2]);
|
|
30
|
+
return [
|
|
31
|
+
match$1[0],
|
|
32
|
+
match$2[0]
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function generateEndpointFunction(endpoint, overrideDir, moduleName) {
|
|
37
|
+
let functionName = CodegenUtils.generateOperationName(endpoint.operationId, endpoint.path, endpoint.method);
|
|
38
|
+
let requestTypeName = functionName + `Request`;
|
|
39
|
+
let hasRequestBody = Stdlib_Option.isSome(endpoint.requestBody);
|
|
40
|
+
let requestBody = Stdlib_Option.getOr(endpoint.requestBody, {
|
|
41
|
+
description: undefined,
|
|
42
|
+
content: {},
|
|
43
|
+
required: false
|
|
44
|
+
});
|
|
45
|
+
let isRequestBodyRequired = Stdlib_Option.getOr(requestBody.required, false);
|
|
46
|
+
let bodyParam = hasRequestBody ? (
|
|
47
|
+
isRequestBodyRequired ? `~body: ` + requestTypeName : `~body: option<` + requestTypeName + `>=?`
|
|
48
|
+
) : "";
|
|
49
|
+
let paramSep = hasRequestBody ? ", " : "";
|
|
50
|
+
let bodyValueConversion = hasRequestBody ? (
|
|
51
|
+
isRequestBodyRequired ? ` let jsonBody = body->S.reverseConvertToJsonOrThrow(` + functionName + `RequestSchema)` : ` let jsonBody = body->Option.map(b => b->S.reverseConvertToJsonOrThrow(` + functionName + `RequestSchema))`
|
|
52
|
+
) : "";
|
|
53
|
+
let successResponse = Stdlib_Array.filterMap([
|
|
54
|
+
"200",
|
|
55
|
+
"201",
|
|
56
|
+
"202",
|
|
57
|
+
"204"
|
|
58
|
+
], code => endpoint.responses[code])[0];
|
|
59
|
+
let responseHandling = Stdlib_Option.mapOr(successResponse, " response", response => Stdlib_Option.mapOr(response.content, " let _ = response\n ()", content => {
|
|
60
|
+
if (Object.entries(content).length !== 0) {
|
|
61
|
+
return ` let value = response->S.parseOrThrow(` + functionName + `ResponseSchema)\n value`;
|
|
62
|
+
} else {
|
|
63
|
+
return " response";
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
let description;
|
|
67
|
+
if (overrideDir !== undefined && moduleName !== undefined) {
|
|
68
|
+
let overrideResult = DocOverride.readOverrideWithValidation(overrideDir, moduleName, functionName, DocOverride.generateEndpointHash(endpoint));
|
|
69
|
+
if (typeof overrideResult !== "object") {
|
|
70
|
+
description = endpoint.description;
|
|
71
|
+
} else {
|
|
72
|
+
switch (overrideResult.TAG) {
|
|
73
|
+
case "ValidOverride" :
|
|
74
|
+
description = overrideResult._0;
|
|
75
|
+
break;
|
|
76
|
+
case "InvalidHash" :
|
|
77
|
+
description = overrideResult.override;
|
|
78
|
+
break;
|
|
79
|
+
case "FileError" :
|
|
80
|
+
description = endpoint.description;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
description = endpoint.description;
|
|
86
|
+
}
|
|
87
|
+
let docComment = CodegenUtils.generateDocString(endpoint.summary, description, undefined);
|
|
88
|
+
let code = `
|
|
89
|
+
|` + docComment.trimEnd() + `
|
|
90
|
+
|let ` + functionName + ` = (` + bodyParam + paramSep + `~fetch: ` + CodegenUtils.fetchTypeSignature + `): promise<` + functionName + `Response> => {
|
|
91
|
+
|` + bodyValueConversion + `
|
|
92
|
+
| fetch(
|
|
93
|
+
| ~url="` + endpoint.path + `",
|
|
94
|
+
| ~method_="` + endpoint.method.toUpperCase() + `",
|
|
95
|
+
| ~body=` + (
|
|
96
|
+
hasRequestBody ? "Some(jsonBody)" : "None"
|
|
97
|
+
) + `,
|
|
98
|
+
| )->Promise.then(response => {
|
|
99
|
+
|` + responseHandling + `
|
|
100
|
+
| ->Promise.resolve
|
|
101
|
+
| })
|
|
102
|
+
|}`;
|
|
103
|
+
return CodegenUtils.trimMargin(code, undefined);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function generateEndpointCode(endpoint, overrideDir, moduleName, modulePrefixOpt) {
|
|
107
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
108
|
+
let functionName = CodegenUtils.generateOperationName(endpoint.operationId, endpoint.path, endpoint.method);
|
|
109
|
+
let requestJsonSchema = getJsonSchemaFromRequestBody(endpoint.requestBody);
|
|
110
|
+
let responseJsonSchema = Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Array.filterMap([
|
|
111
|
+
"200",
|
|
112
|
+
"201",
|
|
113
|
+
"202",
|
|
114
|
+
"204"
|
|
115
|
+
], code => endpoint.responses[code])[0], resp => resp.content), content => Stdlib_Option.flatMap(Object.entries(content)[0], param => param[1].schema));
|
|
116
|
+
let requestPart = Stdlib_Option.mapOr(requestJsonSchema, "", schema => {
|
|
117
|
+
let match = generateTypeCodeAndSchemaCode(schema, functionName + `Request`, functionName + `Request`, modulePrefix);
|
|
118
|
+
return match[0] + `\n\n` + match[1];
|
|
119
|
+
});
|
|
120
|
+
let responsePart = Stdlib_Option.mapOr(responseJsonSchema, `type ` + functionName + `Response = unit`, schema => {
|
|
121
|
+
let match = generateTypeCodeAndSchemaCode(schema, functionName + `Response`, functionName + `Response`, modulePrefix);
|
|
122
|
+
return match[0] + `\n\n` + match[1];
|
|
123
|
+
});
|
|
124
|
+
return [
|
|
125
|
+
requestPart,
|
|
126
|
+
responsePart,
|
|
127
|
+
generateEndpointFunction(endpoint, overrideDir, moduleName)
|
|
128
|
+
].filter(s => s !== "").join("\n\n");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function generateEndpointModule(endpoint, modulePrefixOpt) {
|
|
132
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
133
|
+
let functionName = CodegenUtils.generateOperationName(endpoint.operationId, endpoint.path, endpoint.method);
|
|
134
|
+
let header = CodegenUtils.generateFileHeader(Stdlib_Option.getOr(endpoint.summary, `API: ` + endpoint.path));
|
|
135
|
+
return CodegenUtils.trimMargin(`
|
|
136
|
+
|` + header.trimEnd() + `
|
|
137
|
+
|
|
|
138
|
+
|module ` + JsConvertCase.toPascalCase(functionName) + ` = {
|
|
139
|
+
|` + CodegenUtils.indent(generateEndpointCode(endpoint, undefined, undefined, modulePrefix), 2) + `
|
|
140
|
+
|}
|
|
141
|
+
|`, undefined);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function generateEndpointsModule(moduleName, endpoints, description, overrideDir, modulePrefixOpt) {
|
|
145
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
146
|
+
let header = CodegenUtils.generateFileHeader(Stdlib_Option.getOr(description, `API for ` + moduleName));
|
|
147
|
+
let body = endpoints.map(ep => CodegenUtils.indent(generateEndpointCode(ep, overrideDir, moduleName, modulePrefix), 2)).join("\n\n");
|
|
148
|
+
return CodegenUtils.trimMargin(`
|
|
149
|
+
|` + header.trimEnd() + `
|
|
150
|
+
|
|
|
151
|
+
|module ` + moduleName + ` = {
|
|
152
|
+
|` + body + `
|
|
153
|
+
|}
|
|
154
|
+
|`, undefined);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function generateEndpointSignature(endpoint) {
|
|
158
|
+
let functionName = CodegenUtils.generateOperationName(endpoint.operationId, endpoint.path, endpoint.method);
|
|
159
|
+
let summaryPrefix = Stdlib_Option.mapOr(endpoint.summary, "", s => `// ` + s + `\n`);
|
|
160
|
+
let bodyParam = Stdlib_Option.isSome(endpoint.requestBody) ? "~body: 'body, " : "";
|
|
161
|
+
return summaryPrefix + `let ` + functionName + `: (` + bodyParam + `~fetch: fetchFn) => promise<` + functionName + `Response>`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export {
|
|
165
|
+
getJsonSchemaFromRequestBody,
|
|
166
|
+
generateTypeCodeAndSchemaCode,
|
|
167
|
+
generateEndpointFunction,
|
|
168
|
+
generateEndpointCode,
|
|
169
|
+
generateEndpointModule,
|
|
170
|
+
generateEndpointsModule,
|
|
171
|
+
generateEndpointSignature,
|
|
172
|
+
}
|
|
173
|
+
/* DocOverride Not a pure module */
|