@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,423 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Config from "./types/Config.mjs";
|
|
4
|
+
import * as Pipeline from "./core/Pipeline.mjs";
|
|
5
|
+
import * as Text from "@std/text";
|
|
6
|
+
import * as Belt_Array from "@rescript/runtime/lib/es6/Belt_Array.js";
|
|
7
|
+
import * as FileSystem from "./core/FileSystem.mjs";
|
|
8
|
+
import * as SpecDiffer from "./core/SpecDiffer.mjs";
|
|
9
|
+
import * as SpecMerger from "./core/SpecMerger.mjs";
|
|
10
|
+
import * as DocOverride from "./core/DocOverride.mjs";
|
|
11
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
12
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
13
|
+
import * as OpenAPIParser from "./core/OpenAPIParser.mjs";
|
|
14
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
15
|
+
import * as Stdlib_Result from "@rescript/runtime/lib/es6/Stdlib_Result.js";
|
|
16
|
+
import * as ModuleGenerator from "./generators/ModuleGenerator.mjs";
|
|
17
|
+
import * as SchemaRefResolver from "./core/SchemaRefResolver.mjs";
|
|
18
|
+
import * as DiffReportGenerator from "./generators/DiffReportGenerator.mjs";
|
|
19
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
20
|
+
import * as ThinWrapperGenerator from "./generators/ThinWrapperGenerator.mjs";
|
|
21
|
+
import * as TypeScriptDtsGenerator from "./generators/TypeScriptDtsGenerator.mjs";
|
|
22
|
+
import * as ComponentSchemaGenerator from "./generators/ComponentSchemaGenerator.mjs";
|
|
23
|
+
import * as TypeScriptWrapperGenerator from "./generators/TypeScriptWrapperGenerator.mjs";
|
|
24
|
+
|
|
25
|
+
function generateSingleSpecPure(spec, config) {
|
|
26
|
+
try {
|
|
27
|
+
let targets = Stdlib_Option.getOr(config.targets, Config.defaultTargets());
|
|
28
|
+
let allEndpoints = OpenAPIParser.getAllEndpoints(spec);
|
|
29
|
+
let includeTags = config.includeTags;
|
|
30
|
+
let endpoints = includeTags !== undefined ? OpenAPIParser.filterByTags(allEndpoints, includeTags, Stdlib_Option.getOr(config.excludeTags, [])) : allEndpoints;
|
|
31
|
+
let baseOutput = targets.rescriptApi ? Pipeline.combine([
|
|
32
|
+
ComponentSchemaGenerator.generate(spec, config.outputDir),
|
|
33
|
+
config.modulePerTag ? ModuleGenerator.generateTagModuleFiles(endpoints, config.outputDir, undefined, config.docOverrideDir) : ModuleGenerator.generateFlatModuleFile("API", endpoints, config.outputDir, config.docOverrideDir)
|
|
34
|
+
]) : Pipeline.empty;
|
|
35
|
+
let wrapperOutput = targets.rescriptWrapper ? ThinWrapperGenerator.generateWrapper(spec, endpoints, undefined, config.outputDir, Text.toPascalCase(spec.info.title) + "Wrapper", "", undefined) : Pipeline.empty;
|
|
36
|
+
let dtsOutput = targets.typescriptDts ? TypeScriptDtsGenerator.generate(spec, endpoints, Stdlib_Option.getOr(config.dtsOutputDir, config.outputDir)) : Pipeline.empty;
|
|
37
|
+
let tsWrapperOutput = targets.typescriptWrapper ? TypeScriptWrapperGenerator.generate(endpoints, Stdlib_Option.getOr(config.wrapperOutputDir, config.outputDir), "../generated") : Pipeline.empty;
|
|
38
|
+
return {
|
|
39
|
+
TAG: "Ok",
|
|
40
|
+
_0: Pipeline.combine([
|
|
41
|
+
baseOutput,
|
|
42
|
+
wrapperOutput,
|
|
43
|
+
dtsOutput,
|
|
44
|
+
tsWrapperOutput
|
|
45
|
+
])
|
|
46
|
+
};
|
|
47
|
+
} catch (raw_err) {
|
|
48
|
+
let err = Primitive_exceptions.internalToException(raw_err);
|
|
49
|
+
if (err.RE_EXN_ID === "JsExn") {
|
|
50
|
+
return {
|
|
51
|
+
TAG: "Error",
|
|
52
|
+
_0: {
|
|
53
|
+
TAG: "UnknownError",
|
|
54
|
+
message: Stdlib_Option.getOr(Stdlib_JsExn.message(err._1), "Unknown error"),
|
|
55
|
+
context: undefined
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
} else {
|
|
59
|
+
return {
|
|
60
|
+
TAG: "Error",
|
|
61
|
+
_0: {
|
|
62
|
+
TAG: "UnknownError",
|
|
63
|
+
message: "Unknown error",
|
|
64
|
+
context: undefined
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function generateSingleSpec(spec, config) {
|
|
72
|
+
let err = generateSingleSpecPure(spec, config);
|
|
73
|
+
if (err.TAG !== "Ok") {
|
|
74
|
+
return {
|
|
75
|
+
TAG: "Error",
|
|
76
|
+
_0: err._0
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
let output = err._0;
|
|
80
|
+
let errors = FileSystem.writeFiles(output.files);
|
|
81
|
+
if (errors.TAG !== "Ok") {
|
|
82
|
+
return {
|
|
83
|
+
TAG: "Error",
|
|
84
|
+
_0: {
|
|
85
|
+
TAG: "UnknownError",
|
|
86
|
+
message: `Failed to write files: ` + errors._0.join(", "),
|
|
87
|
+
context: undefined
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
let match = config.generateDocOverrides;
|
|
92
|
+
let overrideFiles;
|
|
93
|
+
if (match !== undefined) {
|
|
94
|
+
if (match) {
|
|
95
|
+
let allEndpoints = OpenAPIParser.getAllEndpoints(spec);
|
|
96
|
+
let includeTags = config.includeTags;
|
|
97
|
+
let endpoints = includeTags !== undefined ? OpenAPIParser.filterByTags(allEndpoints, includeTags, Stdlib_Option.getOr(config.excludeTags, [])) : allEndpoints;
|
|
98
|
+
let files = DocOverride.generateOverrideFiles(spec, endpoints, Stdlib_Option.getOr(config.docOverrideDir, "./docs"), spec.info.title, config.modulePerTag, undefined);
|
|
99
|
+
overrideFiles = Stdlib_Result.getOr(FileSystem.writeFiles(files), []);
|
|
100
|
+
} else {
|
|
101
|
+
overrideFiles = [];
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
overrideFiles = [];
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
TAG: "Ok",
|
|
108
|
+
_0: {
|
|
109
|
+
generatedFiles: errors._0.concat(overrideFiles),
|
|
110
|
+
diff: undefined,
|
|
111
|
+
warnings: output.warnings
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function processForkPure(baseSpec, baseEndpoints, fork, config) {
|
|
117
|
+
try {
|
|
118
|
+
let forkEndpoints = OpenAPIParser.getAllEndpoints(fork.spec);
|
|
119
|
+
let diff = SpecDiffer.generateDiff(baseSpec, fork.spec, baseEndpoints, forkEndpoints);
|
|
120
|
+
let diffReportFile = config.generateDiffReport ? ({
|
|
121
|
+
path: FileSystem.makePath(config.outputDir, fork.name + `-diff.md`),
|
|
122
|
+
content: DiffReportGenerator.generateMarkdownReport(diff, "base", fork.name)
|
|
123
|
+
}) : undefined;
|
|
124
|
+
let match = SpecMerger.mergeSpecs(baseSpec, fork.spec, baseEndpoints, forkEndpoints, config.strategy);
|
|
125
|
+
let sharedSpec = match[0];
|
|
126
|
+
let sharedEndpoints = OpenAPIParser.getAllEndpoints(sharedSpec);
|
|
127
|
+
let extensionEndpoints = OpenAPIParser.getAllEndpoints(match[1]);
|
|
128
|
+
let mergeReportFile_path = FileSystem.makePath(config.outputDir, fork.name + `-merge.md`);
|
|
129
|
+
let mergeReportFile_content = DiffReportGenerator.generateMergeReport(SpecMerger.getMergeStats(baseEndpoints, forkEndpoints, Stdlib_Option.flatMap(baseSpec.components, c => c.schemas), Stdlib_Option.flatMap(fork.spec.components, c => c.schemas)), "base", fork.name);
|
|
130
|
+
let mergeReportFile = {
|
|
131
|
+
path: mergeReportFile_path,
|
|
132
|
+
content: mergeReportFile_content
|
|
133
|
+
};
|
|
134
|
+
let match$1 = config.strategy;
|
|
135
|
+
let codeOutput;
|
|
136
|
+
if (match$1 === "Separate") {
|
|
137
|
+
codeOutput = Pipeline.fromFile({
|
|
138
|
+
path: FileSystem.makePath(config.outputDir, fork.name + `.res`),
|
|
139
|
+
content: ModuleGenerator.generateFlatModuleCode(Text.toPascalCase(fork.name), forkEndpoints, config.docOverrideDir)
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
let baseName = Stdlib_Option.getOrThrow(config.baseInstanceName, "baseInstanceName required");
|
|
143
|
+
let basePrefix = Stdlib_Option.getOr(config.baseModulePrefix, Text.toPascalCase(baseName));
|
|
144
|
+
codeOutput = ModuleGenerator.generateSeparatePerTagModules(baseName, basePrefix, fork.name, undefined, sharedEndpoints, extensionEndpoints, Stdlib_Option.flatMap(sharedSpec.components, c => c.schemas), Stdlib_Option.flatMap(fork.spec.components, c => c.schemas), config.outputDir, config.docOverrideDir);
|
|
145
|
+
}
|
|
146
|
+
let targets = Stdlib_Option.getOr(config.targets, {
|
|
147
|
+
rescriptApi: true,
|
|
148
|
+
rescriptWrapper: false,
|
|
149
|
+
typescriptDts: false,
|
|
150
|
+
typescriptWrapper: false
|
|
151
|
+
});
|
|
152
|
+
let match$2 = config.strategy;
|
|
153
|
+
let match$3;
|
|
154
|
+
match$3 = match$2 === "Separate" ? [
|
|
155
|
+
fork.spec,
|
|
156
|
+
forkEndpoints,
|
|
157
|
+
[],
|
|
158
|
+
""
|
|
159
|
+
] : [
|
|
160
|
+
sharedSpec,
|
|
161
|
+
sharedEndpoints,
|
|
162
|
+
extensionEndpoints,
|
|
163
|
+
Stdlib_Option.getOr(config.baseModulePrefix, Stdlib_Option.getOr(Stdlib_Option.map(config.baseInstanceName, prim => Text.toPascalCase(prim)), ""))
|
|
164
|
+
];
|
|
165
|
+
let wExt = match$3[2];
|
|
166
|
+
let wShared = match$3[1];
|
|
167
|
+
let wSpec = match$3[0];
|
|
168
|
+
let wrapperOutput = targets.rescriptWrapper ? ThinWrapperGenerator.generateWrapper(wSpec, wShared, wExt, FileSystem.makePath(config.outputDir, fork.name), Text.toPascalCase(fork.name) + "Wrapper", Text.toPascalCase(fork.name), match$3[3]) : Pipeline.empty;
|
|
169
|
+
let allWEndpoints = wShared.concat(wExt);
|
|
170
|
+
let dtsOutput = targets.typescriptDts ? TypeScriptDtsGenerator.generate(wSpec, allWEndpoints, FileSystem.makePath(Stdlib_Option.getOr(config.dtsOutputDir, config.outputDir), fork.name)) : Pipeline.empty;
|
|
171
|
+
let tsWrapperOutput = targets.typescriptWrapper ? TypeScriptWrapperGenerator.generate(allWEndpoints, FileSystem.makePath(Stdlib_Option.getOr(config.wrapperOutputDir, config.outputDir), fork.name), `../../generated/` + fork.name) : Pipeline.empty;
|
|
172
|
+
let reports = Pipeline.fromFiles(Belt_Array.concatMany([
|
|
173
|
+
[mergeReportFile],
|
|
174
|
+
Stdlib_Option.getOr(Stdlib_Option.map(diffReportFile, f => [f]), [])
|
|
175
|
+
]));
|
|
176
|
+
return {
|
|
177
|
+
TAG: "Ok",
|
|
178
|
+
_0: Pipeline.combine([
|
|
179
|
+
reports,
|
|
180
|
+
codeOutput,
|
|
181
|
+
wrapperOutput,
|
|
182
|
+
dtsOutput,
|
|
183
|
+
tsWrapperOutput
|
|
184
|
+
])
|
|
185
|
+
};
|
|
186
|
+
} catch (raw_err) {
|
|
187
|
+
let err = Primitive_exceptions.internalToException(raw_err);
|
|
188
|
+
if (err.RE_EXN_ID === "JsExn") {
|
|
189
|
+
return {
|
|
190
|
+
TAG: "Error",
|
|
191
|
+
_0: {
|
|
192
|
+
TAG: "UnknownError",
|
|
193
|
+
message: Stdlib_Option.getOr(Stdlib_JsExn.message(err._1), "Unknown error"),
|
|
194
|
+
context: undefined
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
} else {
|
|
198
|
+
return {
|
|
199
|
+
TAG: "Error",
|
|
200
|
+
_0: {
|
|
201
|
+
TAG: "UnknownError",
|
|
202
|
+
message: "Unknown error",
|
|
203
|
+
context: undefined
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function generateMultiSpecPure(baseSpec, forkSpecs, config) {
|
|
211
|
+
try {
|
|
212
|
+
let baseEndpoints = OpenAPIParser.getAllEndpoints(baseSpec);
|
|
213
|
+
let forkResults = forkSpecs.map(fork => processForkPure(baseSpec, baseEndpoints, fork, config));
|
|
214
|
+
let match = forkResults.find(Stdlib_Result.isError);
|
|
215
|
+
let exit = 0;
|
|
216
|
+
if (match !== undefined) {
|
|
217
|
+
if (match.TAG !== "Ok") {
|
|
218
|
+
return {
|
|
219
|
+
TAG: "Error",
|
|
220
|
+
_0: match._0
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
exit = 1;
|
|
224
|
+
} else {
|
|
225
|
+
exit = 1;
|
|
226
|
+
}
|
|
227
|
+
if (exit === 1) {
|
|
228
|
+
let outputs = Stdlib_Array.filterMap(forkResults, res => {
|
|
229
|
+
if (res.TAG === "Ok") {
|
|
230
|
+
return res._0;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
let targets = Stdlib_Option.getOr(config.targets, Config.defaultTargets());
|
|
234
|
+
let baseName = Stdlib_Option.getOrThrow(config.baseInstanceName, "baseInstanceName required");
|
|
235
|
+
let basePrefix = Stdlib_Option.getOr(config.baseModulePrefix, Text.toPascalCase(baseName));
|
|
236
|
+
let baseOutputDir = FileSystem.makePath(config.outputDir, baseName);
|
|
237
|
+
let baseWrappers = Pipeline.combine([
|
|
238
|
+
targets.rescriptWrapper ? ThinWrapperGenerator.generateWrapper(baseSpec, baseEndpoints, undefined, baseOutputDir, basePrefix + "Wrapper", basePrefix, undefined) : Pipeline.empty,
|
|
239
|
+
targets.typescriptDts ? TypeScriptDtsGenerator.generate(baseSpec, baseEndpoints, FileSystem.makePath(Stdlib_Option.getOr(config.dtsOutputDir, config.outputDir), baseName)) : Pipeline.empty,
|
|
240
|
+
targets.typescriptWrapper ? TypeScriptWrapperGenerator.generate(baseEndpoints, FileSystem.makePath(Stdlib_Option.getOr(config.wrapperOutputDir, config.outputDir), baseName), `../../generated/` + baseName) : Pipeline.empty
|
|
241
|
+
]);
|
|
242
|
+
return {
|
|
243
|
+
TAG: "Ok",
|
|
244
|
+
_0: Pipeline.combine(outputs.concat([baseWrappers]))
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
} catch (raw_err) {
|
|
248
|
+
let err = Primitive_exceptions.internalToException(raw_err);
|
|
249
|
+
if (err.RE_EXN_ID === "JsExn") {
|
|
250
|
+
return {
|
|
251
|
+
TAG: "Error",
|
|
252
|
+
_0: {
|
|
253
|
+
TAG: "UnknownError",
|
|
254
|
+
message: Stdlib_Option.getOr(Stdlib_JsExn.message(err._1), "Unknown error"),
|
|
255
|
+
context: undefined
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
} else {
|
|
259
|
+
return {
|
|
260
|
+
TAG: "Error",
|
|
261
|
+
_0: {
|
|
262
|
+
TAG: "UnknownError",
|
|
263
|
+
message: "Unknown error",
|
|
264
|
+
context: undefined
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async function generateMultiSpec(baseSpec, forkSpecs, config) {
|
|
272
|
+
let err = generateMultiSpecPure(baseSpec, forkSpecs, config);
|
|
273
|
+
if (err.TAG !== "Ok") {
|
|
274
|
+
return {
|
|
275
|
+
TAG: "Error",
|
|
276
|
+
_0: err._0
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
let output = err._0;
|
|
280
|
+
return Stdlib_Result.mapError(Stdlib_Result.map(FileSystem.writeFiles(output.files), filePaths => ({
|
|
281
|
+
generatedFiles: filePaths,
|
|
282
|
+
diff: undefined,
|
|
283
|
+
warnings: output.warnings
|
|
284
|
+
})), errors => ({
|
|
285
|
+
TAG: "UnknownError",
|
|
286
|
+
message: `Failed to write files: ` + errors.join(", "),
|
|
287
|
+
context: undefined
|
|
288
|
+
}));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async function compareSpecs(baseSpec, forkSpec, baseNameOpt, forkNameOpt, outputPath) {
|
|
292
|
+
let baseName = baseNameOpt !== undefined ? baseNameOpt : "base";
|
|
293
|
+
let forkName = forkNameOpt !== undefined ? forkNameOpt : "fork";
|
|
294
|
+
let diff = SpecDiffer.generateDiff(baseSpec, forkSpec, OpenAPIParser.getAllEndpoints(baseSpec), OpenAPIParser.getAllEndpoints(forkSpec));
|
|
295
|
+
Stdlib_Option.forEach(outputPath, path => {
|
|
296
|
+
FileSystem.writeFile({
|
|
297
|
+
path: path,
|
|
298
|
+
content: DiffReportGenerator.generateMarkdownReport(diff, baseName, forkName)
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
return diff;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async function generate(config) {
|
|
305
|
+
let message = await SchemaRefResolver.resolve(config.specPath, undefined);
|
|
306
|
+
if (message.TAG !== "Ok") {
|
|
307
|
+
return {
|
|
308
|
+
TAG: "Error",
|
|
309
|
+
_0: {
|
|
310
|
+
TAG: "SpecResolutionError",
|
|
311
|
+
url: config.specPath,
|
|
312
|
+
message: message._0
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
let baseSpec = message._0;
|
|
317
|
+
let forkConfigs = config.forkSpecs;
|
|
318
|
+
if (forkConfigs === undefined) {
|
|
319
|
+
return await generateSingleSpec(baseSpec, config);
|
|
320
|
+
}
|
|
321
|
+
if (forkConfigs.length === 0) {
|
|
322
|
+
return await generateSingleSpec(baseSpec, config);
|
|
323
|
+
}
|
|
324
|
+
let forkResults = await Promise.all(forkConfigs.map(async f => Stdlib_Result.map(await SchemaRefResolver.resolve(f.specPath, undefined), spec => ({
|
|
325
|
+
name: f.name,
|
|
326
|
+
spec: spec
|
|
327
|
+
}))));
|
|
328
|
+
let match = forkResults.find(Stdlib_Result.isError);
|
|
329
|
+
if (match !== undefined && match.TAG !== "Ok") {
|
|
330
|
+
return {
|
|
331
|
+
TAG: "Error",
|
|
332
|
+
_0: {
|
|
333
|
+
TAG: "SpecResolutionError",
|
|
334
|
+
url: "",
|
|
335
|
+
message: match._0
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
return await generateMultiSpec(baseSpec, Stdlib_Array.filterMap(forkResults, res => {
|
|
340
|
+
if (res.TAG === "Ok") {
|
|
341
|
+
return res._0;
|
|
342
|
+
}
|
|
343
|
+
}), config);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function createDefaultConfig(url, outputDir) {
|
|
347
|
+
return {
|
|
348
|
+
specPath: url,
|
|
349
|
+
forkSpecs: undefined,
|
|
350
|
+
outputDir: outputDir,
|
|
351
|
+
strategy: "SharedBase",
|
|
352
|
+
modulePerTag: true,
|
|
353
|
+
includeTags: undefined,
|
|
354
|
+
excludeTags: undefined,
|
|
355
|
+
generateDiffReport: true,
|
|
356
|
+
breakingChangeHandling: "Warn",
|
|
357
|
+
generateDocOverrides: undefined,
|
|
358
|
+
docOverrideDir: undefined,
|
|
359
|
+
targets: undefined,
|
|
360
|
+
dtsOutputDir: undefined,
|
|
361
|
+
wrapperOutputDir: undefined,
|
|
362
|
+
baseInstanceName: undefined,
|
|
363
|
+
baseModulePrefix: undefined
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async function generateFromUrl(url, outputDir, config) {
|
|
368
|
+
let init = Stdlib_Option.getOr(config, createDefaultConfig(url, outputDir));
|
|
369
|
+
return await generate({
|
|
370
|
+
specPath: url,
|
|
371
|
+
forkSpecs: init.forkSpecs,
|
|
372
|
+
outputDir: init.outputDir,
|
|
373
|
+
strategy: init.strategy,
|
|
374
|
+
modulePerTag: init.modulePerTag,
|
|
375
|
+
includeTags: init.includeTags,
|
|
376
|
+
excludeTags: init.excludeTags,
|
|
377
|
+
generateDiffReport: init.generateDiffReport,
|
|
378
|
+
breakingChangeHandling: init.breakingChangeHandling,
|
|
379
|
+
generateDocOverrides: init.generateDocOverrides,
|
|
380
|
+
docOverrideDir: init.docOverrideDir,
|
|
381
|
+
targets: init.targets,
|
|
382
|
+
dtsOutputDir: init.dtsOutputDir,
|
|
383
|
+
wrapperOutputDir: init.wrapperOutputDir,
|
|
384
|
+
baseInstanceName: init.baseInstanceName,
|
|
385
|
+
baseModulePrefix: init.baseModulePrefix
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function generateFromFile(filePath, outputDir, config) {
|
|
390
|
+
let init = Stdlib_Option.getOr(config, createDefaultConfig(filePath, outputDir));
|
|
391
|
+
return await generate({
|
|
392
|
+
specPath: filePath,
|
|
393
|
+
forkSpecs: init.forkSpecs,
|
|
394
|
+
outputDir: init.outputDir,
|
|
395
|
+
strategy: init.strategy,
|
|
396
|
+
modulePerTag: init.modulePerTag,
|
|
397
|
+
includeTags: init.includeTags,
|
|
398
|
+
excludeTags: init.excludeTags,
|
|
399
|
+
generateDiffReport: init.generateDiffReport,
|
|
400
|
+
breakingChangeHandling: init.breakingChangeHandling,
|
|
401
|
+
generateDocOverrides: init.generateDocOverrides,
|
|
402
|
+
docOverrideDir: init.docOverrideDir,
|
|
403
|
+
targets: init.targets,
|
|
404
|
+
dtsOutputDir: init.dtsOutputDir,
|
|
405
|
+
wrapperOutputDir: init.wrapperOutputDir,
|
|
406
|
+
baseInstanceName: init.baseInstanceName,
|
|
407
|
+
baseModulePrefix: init.baseModulePrefix
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export {
|
|
412
|
+
generateSingleSpecPure,
|
|
413
|
+
generateSingleSpec,
|
|
414
|
+
processForkPure,
|
|
415
|
+
generateMultiSpecPure,
|
|
416
|
+
generateMultiSpec,
|
|
417
|
+
compareSpecs,
|
|
418
|
+
generate,
|
|
419
|
+
createDefaultConfig,
|
|
420
|
+
generateFromUrl,
|
|
421
|
+
generateFromFile,
|
|
422
|
+
}
|
|
423
|
+
/* @std/text Not a pure module */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as CodegenError from "./types/CodegenError.mjs";
|
|
4
|
+
|
|
5
|
+
let Warning_toString = CodegenError.Warning.toString;
|
|
6
|
+
|
|
7
|
+
let Warning_print = CodegenError.Warning.print;
|
|
8
|
+
|
|
9
|
+
let Warning = {
|
|
10
|
+
toString: Warning_toString,
|
|
11
|
+
print: Warning_print
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let CodegenError$1;
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
CodegenError$1 as CodegenError,
|
|
18
|
+
Warning,
|
|
19
|
+
}
|
|
20
|
+
/* No side effect */
|
|
@@ -0,0 +1,186 @@
|
|
|
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
|
+
|
|
6
|
+
function sanitizeIdentifier(str) {
|
|
7
|
+
return str.replaceAll("{", "").replaceAll("}", "").replaceAll("[", "").replaceAll("]", "").replaceAll(".", "_").replaceAll("-", "_").replaceAll("/", "_").replaceAll(" ", "_");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function generateTypeName(prefixOpt, path, suffix) {
|
|
11
|
+
let prefix = prefixOpt !== undefined ? prefixOpt : "";
|
|
12
|
+
let cleaned = sanitizeIdentifier(path.replaceAll("/", "_")).split("_").filter(part => part !== "").map(prim => Text.toPascalCase(prim)).join("");
|
|
13
|
+
return prefix + cleaned + suffix;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function generateOperationName(operationId, path, method) {
|
|
17
|
+
if (operationId !== undefined) {
|
|
18
|
+
return Text.toCamelCase(sanitizeIdentifier(operationId));
|
|
19
|
+
} else {
|
|
20
|
+
return method.toLowerCase() + path.split("/").filter(part => {
|
|
21
|
+
if (part !== "") {
|
|
22
|
+
return !part.startsWith("{");
|
|
23
|
+
} else {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}).map(prim => Text.toCamelCase(prim)).join("");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function escapeString(str) {
|
|
31
|
+
return str.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"").replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll("\t", "\\t");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function generateFileHeader(description) {
|
|
35
|
+
return `// ` + description + `
|
|
36
|
+
// Generated by @f3liz/rescript-autogen-openapi
|
|
37
|
+
// DO NOT EDIT - This file is auto-generated
|
|
38
|
+
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function indent(code, level) {
|
|
43
|
+
let spaces = " ".repeat(level);
|
|
44
|
+
return code.split("\n").map(line => {
|
|
45
|
+
if (line.trim() === "") {
|
|
46
|
+
return "";
|
|
47
|
+
} else {
|
|
48
|
+
return spaces + line;
|
|
49
|
+
}
|
|
50
|
+
}).join("\n");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function trimMargin(text, marginPrefixOpt) {
|
|
54
|
+
let marginPrefix = marginPrefixOpt !== undefined ? marginPrefixOpt : "|";
|
|
55
|
+
return text.split("\n").map(line => {
|
|
56
|
+
let trimmed = line.trimStart();
|
|
57
|
+
if (trimmed.startsWith(marginPrefix)) {
|
|
58
|
+
return trimmed.slice(marginPrefix.length);
|
|
59
|
+
} else {
|
|
60
|
+
return line;
|
|
61
|
+
}
|
|
62
|
+
}).join("\n").trim();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let rescriptKeywords = [
|
|
66
|
+
"and",
|
|
67
|
+
"as",
|
|
68
|
+
"assert",
|
|
69
|
+
"async",
|
|
70
|
+
"await",
|
|
71
|
+
"catch",
|
|
72
|
+
"class",
|
|
73
|
+
"constraint",
|
|
74
|
+
"do",
|
|
75
|
+
"done",
|
|
76
|
+
"downto",
|
|
77
|
+
"else",
|
|
78
|
+
"end",
|
|
79
|
+
"exception",
|
|
80
|
+
"external",
|
|
81
|
+
"false",
|
|
82
|
+
"for",
|
|
83
|
+
"fun",
|
|
84
|
+
"function",
|
|
85
|
+
"functor",
|
|
86
|
+
"if",
|
|
87
|
+
"in",
|
|
88
|
+
"include",
|
|
89
|
+
"inherit",
|
|
90
|
+
"initializer",
|
|
91
|
+
"lazy",
|
|
92
|
+
"let",
|
|
93
|
+
"method",
|
|
94
|
+
"module",
|
|
95
|
+
"mutable",
|
|
96
|
+
"new",
|
|
97
|
+
"nonrec",
|
|
98
|
+
"object",
|
|
99
|
+
"of",
|
|
100
|
+
"open",
|
|
101
|
+
"or",
|
|
102
|
+
"private",
|
|
103
|
+
"rec",
|
|
104
|
+
"sig",
|
|
105
|
+
"struct",
|
|
106
|
+
"switch",
|
|
107
|
+
"then",
|
|
108
|
+
"to",
|
|
109
|
+
"true",
|
|
110
|
+
"try",
|
|
111
|
+
"type",
|
|
112
|
+
"val",
|
|
113
|
+
"virtual",
|
|
114
|
+
"when",
|
|
115
|
+
"while",
|
|
116
|
+
"with"
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
function escapeKeyword(name) {
|
|
120
|
+
if (rescriptKeywords.includes(name)) {
|
|
121
|
+
return name + "_";
|
|
122
|
+
} else {
|
|
123
|
+
return name;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function generateDocComment(summary, description, param) {
|
|
128
|
+
if (summary !== undefined) {
|
|
129
|
+
if (description !== undefined) {
|
|
130
|
+
return `// ` + summary + `\n// ` + description + `\n`;
|
|
131
|
+
} else {
|
|
132
|
+
return `// ` + summary + `\n`;
|
|
133
|
+
}
|
|
134
|
+
} else if (description !== undefined) {
|
|
135
|
+
return `// ` + description + `\n`;
|
|
136
|
+
} else {
|
|
137
|
+
return "";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function generateDocString(summary, description, param) {
|
|
142
|
+
let content = summary !== undefined ? (
|
|
143
|
+
description !== undefined ? (
|
|
144
|
+
summary === description ? summary : summary + "\n\n" + description
|
|
145
|
+
) : summary
|
|
146
|
+
) : (
|
|
147
|
+
description !== undefined ? description : undefined
|
|
148
|
+
);
|
|
149
|
+
return Stdlib_Option.getOr(Stdlib_Option.map(content, text => {
|
|
150
|
+
let lines = text.trim().split("\n").map(prim => prim.trim());
|
|
151
|
+
let len = lines.length;
|
|
152
|
+
if (len !== 1) {
|
|
153
|
+
if (len !== 0) {
|
|
154
|
+
return "/**\n" + lines.map(l => {
|
|
155
|
+
if (l === "") {
|
|
156
|
+
return " *";
|
|
157
|
+
} else {
|
|
158
|
+
return ` * ` + l;
|
|
159
|
+
}
|
|
160
|
+
}).join("\n") + "\n */\n";
|
|
161
|
+
} else {
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
let line = lines[0];
|
|
166
|
+
return `/** ` + line + ` */\n`;
|
|
167
|
+
}), "");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let fetchTypeSignature = "(~url: string, ~method_: string, ~body: option<JSON.t>) => Promise.t<JSON.t>";
|
|
171
|
+
|
|
172
|
+
export {
|
|
173
|
+
sanitizeIdentifier,
|
|
174
|
+
generateTypeName,
|
|
175
|
+
generateOperationName,
|
|
176
|
+
escapeString,
|
|
177
|
+
generateFileHeader,
|
|
178
|
+
indent,
|
|
179
|
+
trimMargin,
|
|
180
|
+
rescriptKeywords,
|
|
181
|
+
escapeKeyword,
|
|
182
|
+
generateDocComment,
|
|
183
|
+
generateDocString,
|
|
184
|
+
fetchTypeSignature,
|
|
185
|
+
}
|
|
186
|
+
/* @std/text Not a pure module */
|