@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,543 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as SchemaIR from "../core/SchemaIR.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 JsConvertCase from "js-convert-case";
|
|
8
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
9
|
+
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
10
|
+
import * as GenerationContext from "../types/GenerationContext.mjs";
|
|
11
|
+
import * as ReferenceResolver from "../core/ReferenceResolver.mjs";
|
|
12
|
+
|
|
13
|
+
function applyConstraints(base, min, max, toString) {
|
|
14
|
+
let s1 = min !== undefined ? base + `->S.min(` + toString(Primitive_option.valFromOption(min)) + `)` : base;
|
|
15
|
+
if (max !== undefined) {
|
|
16
|
+
return s1 + `->S.max(` + toString(Primitive_option.valFromOption(max)) + `)`;
|
|
17
|
+
} else {
|
|
18
|
+
return s1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function generateSchemaWithContext(ctx, depthOpt, extractedTypeMap, irType) {
|
|
23
|
+
let depth = depthOpt !== undefined ? depthOpt : 0;
|
|
24
|
+
if (depth > 100) {
|
|
25
|
+
GenerationContext.addWarning(ctx, {
|
|
26
|
+
TAG: "DepthLimitReached",
|
|
27
|
+
depth: depth,
|
|
28
|
+
path: ctx.path
|
|
29
|
+
});
|
|
30
|
+
return "S.json";
|
|
31
|
+
}
|
|
32
|
+
let recurse = nextIrType => generateSchemaWithContext(ctx, depth + 1 | 0, extractedTypeMap, nextIrType);
|
|
33
|
+
let foundExtracted = extractedTypeMap !== undefined ? extractedTypeMap.find(param => SchemaIR.equals(param.irType, irType)) : undefined;
|
|
34
|
+
if (foundExtracted !== undefined) {
|
|
35
|
+
return foundExtracted.typeName + `Schema`;
|
|
36
|
+
}
|
|
37
|
+
if (typeof irType !== "object") {
|
|
38
|
+
switch (irType) {
|
|
39
|
+
case "Boolean" :
|
|
40
|
+
return "S.bool";
|
|
41
|
+
case "Null" :
|
|
42
|
+
return "S.null";
|
|
43
|
+
case "Unknown" :
|
|
44
|
+
return "S.json";
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
switch (irType.TAG) {
|
|
48
|
+
case "String" :
|
|
49
|
+
let c = irType.constraints;
|
|
50
|
+
let s = applyConstraints("S.string", c.minLength, c.maxLength, v => v.toString());
|
|
51
|
+
let p = c.pattern;
|
|
52
|
+
if (p !== undefined) {
|
|
53
|
+
return s + `->S.pattern(%re("/` + CodegenUtils.escapeString(p) + `/"))`;
|
|
54
|
+
} else {
|
|
55
|
+
return s;
|
|
56
|
+
}
|
|
57
|
+
case "Number" :
|
|
58
|
+
let c$1 = irType.constraints;
|
|
59
|
+
return applyConstraints("S.float", c$1.minimum, c$1.maximum, v => (v | 0).toString());
|
|
60
|
+
case "Integer" :
|
|
61
|
+
let c$2 = irType.constraints;
|
|
62
|
+
return applyConstraints("S.int", c$2.minimum, c$2.maximum, v => (v | 0).toString());
|
|
63
|
+
case "Array" :
|
|
64
|
+
let c$3 = irType.constraints;
|
|
65
|
+
return applyConstraints(`S.array(` + recurse(irType.items) + `)`, c$3.minItems, c$3.maxItems, v => v.toString());
|
|
66
|
+
case "Object" :
|
|
67
|
+
let additionalProperties = irType.additionalProperties;
|
|
68
|
+
let properties = irType.properties;
|
|
69
|
+
if (properties.length === 0) {
|
|
70
|
+
if (additionalProperties !== undefined) {
|
|
71
|
+
return `S.dict(` + recurse(additionalProperties) + `)`;
|
|
72
|
+
} else {
|
|
73
|
+
return "S.dict(S.json)";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
let fields = properties.map(param => {
|
|
77
|
+
let fieldType = param[1];
|
|
78
|
+
let name = param[0];
|
|
79
|
+
let schemaCode = recurse(fieldType);
|
|
80
|
+
let camelName = CodegenUtils.escapeKeyword(JsConvertCase.toCamelCase(name));
|
|
81
|
+
let alreadyNullable = true;
|
|
82
|
+
if (!schemaCode.startsWith("S.nullableAsOption(")) {
|
|
83
|
+
let tmp;
|
|
84
|
+
if (typeof fieldType !== "object") {
|
|
85
|
+
tmp = false;
|
|
86
|
+
} else {
|
|
87
|
+
switch (fieldType.TAG) {
|
|
88
|
+
case "Union" :
|
|
89
|
+
tmp = fieldType._0.some(t => {
|
|
90
|
+
if (typeof t !== "object") {
|
|
91
|
+
return t === "Null";
|
|
92
|
+
}
|
|
93
|
+
if (t.TAG !== "Literal") {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
let tmp = t._0;
|
|
97
|
+
return typeof tmp !== "object";
|
|
98
|
+
});
|
|
99
|
+
break;
|
|
100
|
+
case "Option" :
|
|
101
|
+
tmp = true;
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
tmp = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
alreadyNullable = tmp;
|
|
108
|
+
}
|
|
109
|
+
if (param[2]) {
|
|
110
|
+
return ` ` + camelName + `: s.field("` + name + `", ` + schemaCode + `),`;
|
|
111
|
+
} else if (alreadyNullable) {
|
|
112
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", ` + schemaCode + `, None),`;
|
|
113
|
+
} else {
|
|
114
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", S.nullableAsOption(` + schemaCode + `), None),`;
|
|
115
|
+
}
|
|
116
|
+
}).join("\n");
|
|
117
|
+
return `S.object(s => {\n` + fields + `\n })`;
|
|
118
|
+
case "Literal" :
|
|
119
|
+
let value = irType._0;
|
|
120
|
+
if (typeof value !== "object") {
|
|
121
|
+
return "S.literal(null)";
|
|
122
|
+
}
|
|
123
|
+
switch (value.TAG) {
|
|
124
|
+
case "StringLiteral" :
|
|
125
|
+
return `S.literal("` + CodegenUtils.escapeString(value._0) + `")`;
|
|
126
|
+
case "NumberLiteral" :
|
|
127
|
+
return `S.literal(` + value._0.toString() + `)`;
|
|
128
|
+
case "BooleanLiteral" :
|
|
129
|
+
return `S.literal(` + (
|
|
130
|
+
value._0 ? "true" : "false"
|
|
131
|
+
) + `)`;
|
|
132
|
+
}
|
|
133
|
+
case "Union" :
|
|
134
|
+
let types = irType._0;
|
|
135
|
+
let nonNullTypes = types.filter(t => {
|
|
136
|
+
if (typeof t !== "object") {
|
|
137
|
+
return t !== "Null";
|
|
138
|
+
}
|
|
139
|
+
if (t.TAG !== "Literal") {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
let tmp = t._0;
|
|
143
|
+
return typeof tmp === "object";
|
|
144
|
+
});
|
|
145
|
+
let hasNull = nonNullTypes.length < types.length;
|
|
146
|
+
if (hasNull && nonNullTypes.length === 1) {
|
|
147
|
+
return `S.nullableAsOption(` + recurse(nonNullTypes[0]) + `)`;
|
|
148
|
+
}
|
|
149
|
+
let effectiveTypes = hasNull ? nonNullTypes : types;
|
|
150
|
+
let match = Stdlib_Array.reduce(effectiveTypes, [
|
|
151
|
+
false,
|
|
152
|
+
false,
|
|
153
|
+
undefined,
|
|
154
|
+
undefined
|
|
155
|
+
], (param, t) => {
|
|
156
|
+
let arrItem = param[2];
|
|
157
|
+
let hArr = param[0];
|
|
158
|
+
if (typeof t !== "object" || t.TAG !== "Array") {
|
|
159
|
+
return [
|
|
160
|
+
hArr,
|
|
161
|
+
true,
|
|
162
|
+
arrItem,
|
|
163
|
+
t
|
|
164
|
+
];
|
|
165
|
+
} else {
|
|
166
|
+
return [
|
|
167
|
+
true,
|
|
168
|
+
param[1],
|
|
169
|
+
t.items,
|
|
170
|
+
param[3]
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
let arrayItemType = match[2];
|
|
175
|
+
let result;
|
|
176
|
+
if (match[0] && match[1] && effectiveTypes.length === 2 && SchemaIR.equals(Stdlib_Option.getOr(arrayItemType, "Unknown"), Stdlib_Option.getOr(match[3], "Unknown"))) {
|
|
177
|
+
result = `S.array(` + recurse(Stdlib_Option.getOr(arrayItemType, "Unknown")) + `)`;
|
|
178
|
+
} else if (effectiveTypes.every(t => {
|
|
179
|
+
if (typeof t !== "object") {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
if (t.TAG !== "Literal") {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
let tmp = t._0;
|
|
186
|
+
if (typeof tmp !== "object") {
|
|
187
|
+
return false;
|
|
188
|
+
} else {
|
|
189
|
+
return tmp.TAG === "StringLiteral";
|
|
190
|
+
}
|
|
191
|
+
}) && effectiveTypes.length !== 0 && effectiveTypes.length <= 50) {
|
|
192
|
+
result = `S.union([` + effectiveTypes.map(recurse).join(", ") + `])`;
|
|
193
|
+
} else if (effectiveTypes.length !== 0) {
|
|
194
|
+
let runtimeKinds = {};
|
|
195
|
+
effectiveTypes.forEach(t => {
|
|
196
|
+
let kind;
|
|
197
|
+
if (typeof t !== "object") {
|
|
198
|
+
switch (t) {
|
|
199
|
+
case "Boolean" :
|
|
200
|
+
kind = "boolean";
|
|
201
|
+
break;
|
|
202
|
+
case "Null" :
|
|
203
|
+
kind = "null";
|
|
204
|
+
break;
|
|
205
|
+
default:
|
|
206
|
+
kind = "unknown";
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
switch (t.TAG) {
|
|
210
|
+
case "String" :
|
|
211
|
+
kind = "string";
|
|
212
|
+
break;
|
|
213
|
+
case "Number" :
|
|
214
|
+
case "Integer" :
|
|
215
|
+
kind = "number";
|
|
216
|
+
break;
|
|
217
|
+
case "Array" :
|
|
218
|
+
kind = "array";
|
|
219
|
+
break;
|
|
220
|
+
case "Literal" :
|
|
221
|
+
let tmp = t._0;
|
|
222
|
+
if (typeof tmp !== "object") {
|
|
223
|
+
kind = "null";
|
|
224
|
+
} else {
|
|
225
|
+
switch (tmp.TAG) {
|
|
226
|
+
case "StringLiteral" :
|
|
227
|
+
kind = "string";
|
|
228
|
+
break;
|
|
229
|
+
case "NumberLiteral" :
|
|
230
|
+
kind = "number";
|
|
231
|
+
break;
|
|
232
|
+
case "BooleanLiteral" :
|
|
233
|
+
kind = "boolean";
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
case "Object" :
|
|
239
|
+
case "Intersection" :
|
|
240
|
+
case "Reference" :
|
|
241
|
+
kind = "object";
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
kind = "unknown";
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
let count = Stdlib_Option.getOr(runtimeKinds[kind], 0);
|
|
248
|
+
runtimeKinds[kind] = count + 1 | 0;
|
|
249
|
+
});
|
|
250
|
+
let canUnbox = Object.values(runtimeKinds).every(count => count <= 1);
|
|
251
|
+
if (canUnbox) {
|
|
252
|
+
let rawNames = effectiveTypes.map(CodegenUtils.variantConstructorName);
|
|
253
|
+
let names = CodegenUtils.deduplicateNames(rawNames);
|
|
254
|
+
let branches = effectiveTypes.map((memberType, i) => {
|
|
255
|
+
let constructorName = names[i];
|
|
256
|
+
if (typeof memberType === "object" && memberType.TAG === "Object") {
|
|
257
|
+
let additionalProperties = memberType.additionalProperties;
|
|
258
|
+
let properties = memberType.properties;
|
|
259
|
+
if (properties.length === 0) {
|
|
260
|
+
if (additionalProperties !== undefined) {
|
|
261
|
+
return `S.dict(` + recurse(additionalProperties) + `)->S.shape(v => ` + constructorName + `(v))`;
|
|
262
|
+
} else {
|
|
263
|
+
return `S.dict(S.json)->S.shape(v => ` + constructorName + `(v))`;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
let fields = properties.map(param => {
|
|
267
|
+
let fieldType = param[1];
|
|
268
|
+
let name = param[0];
|
|
269
|
+
let schemaCode = recurse(fieldType);
|
|
270
|
+
let camelName = CodegenUtils.escapeKeyword(JsConvertCase.toCamelCase(name));
|
|
271
|
+
let alreadyNullable = true;
|
|
272
|
+
if (!schemaCode.startsWith("S.nullableAsOption(")) {
|
|
273
|
+
let tmp;
|
|
274
|
+
if (typeof fieldType !== "object") {
|
|
275
|
+
tmp = false;
|
|
276
|
+
} else {
|
|
277
|
+
switch (fieldType.TAG) {
|
|
278
|
+
case "Union" :
|
|
279
|
+
tmp = fieldType._0.some(t => {
|
|
280
|
+
if (typeof t !== "object") {
|
|
281
|
+
return t === "Null";
|
|
282
|
+
}
|
|
283
|
+
if (t.TAG !== "Literal") {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
let tmp = t._0;
|
|
287
|
+
return typeof tmp !== "object";
|
|
288
|
+
});
|
|
289
|
+
break;
|
|
290
|
+
case "Option" :
|
|
291
|
+
tmp = true;
|
|
292
|
+
break;
|
|
293
|
+
default:
|
|
294
|
+
tmp = false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
alreadyNullable = tmp;
|
|
298
|
+
}
|
|
299
|
+
if (param[2]) {
|
|
300
|
+
return ` ` + camelName + `: s.field("` + name + `", ` + schemaCode + `),`;
|
|
301
|
+
} else if (alreadyNullable) {
|
|
302
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", ` + schemaCode + `, None),`;
|
|
303
|
+
} else {
|
|
304
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", S.nullableAsOption(` + schemaCode + `), None),`;
|
|
305
|
+
}
|
|
306
|
+
}).join("\n");
|
|
307
|
+
return `S.object(s => ` + constructorName + `({\n` + fields + `\n }))`;
|
|
308
|
+
}
|
|
309
|
+
let innerSchema = recurse(memberType);
|
|
310
|
+
return innerSchema + `->S.shape(v => ` + constructorName + `(v))`;
|
|
311
|
+
});
|
|
312
|
+
result = `S.union([` + branches.join(", ") + `])`;
|
|
313
|
+
} else {
|
|
314
|
+
result = recurse(effectiveTypes[effectiveTypes.length - 1 | 0]);
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
result = "S.json";
|
|
318
|
+
}
|
|
319
|
+
if (hasNull) {
|
|
320
|
+
return `S.nullableAsOption(` + result + `)`;
|
|
321
|
+
} else {
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
case "Intersection" :
|
|
325
|
+
let types$1 = irType._0;
|
|
326
|
+
if (types$1.every(t => {
|
|
327
|
+
if (typeof t !== "object") {
|
|
328
|
+
return false;
|
|
329
|
+
} else {
|
|
330
|
+
return t.TAG === "Reference";
|
|
331
|
+
}
|
|
332
|
+
}) && types$1.length !== 0) {
|
|
333
|
+
return recurse(Stdlib_Option.getOr(types$1[types$1.length - 1 | 0], "Unknown"));
|
|
334
|
+
}
|
|
335
|
+
let match$1 = Stdlib_Array.reduce(types$1, [
|
|
336
|
+
[],
|
|
337
|
+
[]
|
|
338
|
+
], (param, t) => {
|
|
339
|
+
let nonObj = param[1];
|
|
340
|
+
let props = param[0];
|
|
341
|
+
if (typeof t !== "object") {
|
|
342
|
+
return [
|
|
343
|
+
props,
|
|
344
|
+
nonObj.concat([t])
|
|
345
|
+
];
|
|
346
|
+
} else if (t.TAG === "Object") {
|
|
347
|
+
return [
|
|
348
|
+
props.concat(t.properties),
|
|
349
|
+
nonObj
|
|
350
|
+
];
|
|
351
|
+
} else {
|
|
352
|
+
return [
|
|
353
|
+
props,
|
|
354
|
+
nonObj.concat([t])
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
let nonObjectTypes = match$1[1];
|
|
359
|
+
let objectProps = match$1[0];
|
|
360
|
+
if (objectProps.length !== 0 && nonObjectTypes.length === 0) {
|
|
361
|
+
let fields$1 = objectProps.map(param => {
|
|
362
|
+
let fieldType = param[1];
|
|
363
|
+
let name = param[0];
|
|
364
|
+
let schemaCode = recurse(fieldType);
|
|
365
|
+
let camelName = CodegenUtils.escapeKeyword(JsConvertCase.toCamelCase(name));
|
|
366
|
+
let alreadyNullable = true;
|
|
367
|
+
if (!schemaCode.startsWith("S.nullableAsOption(")) {
|
|
368
|
+
let tmp;
|
|
369
|
+
if (typeof fieldType !== "object") {
|
|
370
|
+
tmp = false;
|
|
371
|
+
} else {
|
|
372
|
+
switch (fieldType.TAG) {
|
|
373
|
+
case "Union" :
|
|
374
|
+
tmp = fieldType._0.some(t => {
|
|
375
|
+
if (typeof t !== "object") {
|
|
376
|
+
return t === "Null";
|
|
377
|
+
}
|
|
378
|
+
if (t.TAG !== "Literal") {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
let tmp = t._0;
|
|
382
|
+
return typeof tmp !== "object";
|
|
383
|
+
});
|
|
384
|
+
break;
|
|
385
|
+
case "Option" :
|
|
386
|
+
tmp = true;
|
|
387
|
+
break;
|
|
388
|
+
default:
|
|
389
|
+
tmp = false;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
alreadyNullable = tmp;
|
|
393
|
+
}
|
|
394
|
+
if (param[2]) {
|
|
395
|
+
return ` ` + camelName + `: s.field("` + name + `", ` + schemaCode + `),`;
|
|
396
|
+
} else if (alreadyNullable) {
|
|
397
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", ` + schemaCode + `, None),`;
|
|
398
|
+
} else {
|
|
399
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", S.nullableAsOption(` + schemaCode + `), None),`;
|
|
400
|
+
}
|
|
401
|
+
}).join("\n");
|
|
402
|
+
return `S.object(s => {\n` + fields$1 + `\n })`;
|
|
403
|
+
}
|
|
404
|
+
if (nonObjectTypes.length !== 0 && objectProps.length === 0) {
|
|
405
|
+
return recurse(Stdlib_Option.getOr(types$1[types$1.length - 1 | 0], "Unknown"));
|
|
406
|
+
}
|
|
407
|
+
GenerationContext.addWarning(ctx, {
|
|
408
|
+
TAG: "IntersectionNotFullySupported",
|
|
409
|
+
location: ctx.path,
|
|
410
|
+
note: "Mixed object/non-object intersection"
|
|
411
|
+
});
|
|
412
|
+
let fields$2 = objectProps.map(param => {
|
|
413
|
+
let fieldType = param[1];
|
|
414
|
+
let name = param[0];
|
|
415
|
+
let schemaCode = recurse(fieldType);
|
|
416
|
+
let camelName = CodegenUtils.escapeKeyword(JsConvertCase.toCamelCase(name));
|
|
417
|
+
let alreadyNullable = true;
|
|
418
|
+
if (!schemaCode.startsWith("S.nullableAsOption(")) {
|
|
419
|
+
let tmp;
|
|
420
|
+
if (typeof fieldType !== "object") {
|
|
421
|
+
tmp = false;
|
|
422
|
+
} else {
|
|
423
|
+
switch (fieldType.TAG) {
|
|
424
|
+
case "Union" :
|
|
425
|
+
tmp = fieldType._0.some(t => {
|
|
426
|
+
if (typeof t !== "object") {
|
|
427
|
+
return t === "Null";
|
|
428
|
+
}
|
|
429
|
+
if (t.TAG !== "Literal") {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
let tmp = t._0;
|
|
433
|
+
return typeof tmp !== "object";
|
|
434
|
+
});
|
|
435
|
+
break;
|
|
436
|
+
case "Option" :
|
|
437
|
+
tmp = true;
|
|
438
|
+
break;
|
|
439
|
+
default:
|
|
440
|
+
tmp = false;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
alreadyNullable = tmp;
|
|
444
|
+
}
|
|
445
|
+
if (param[2]) {
|
|
446
|
+
return ` ` + camelName + `: s.field("` + name + `", ` + schemaCode + `),`;
|
|
447
|
+
} else if (alreadyNullable) {
|
|
448
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", ` + schemaCode + `, None),`;
|
|
449
|
+
} else {
|
|
450
|
+
return ` ` + camelName + `: s.fieldOr("` + name + `", S.nullableAsOption(` + schemaCode + `), None),`;
|
|
451
|
+
}
|
|
452
|
+
}).join("\n");
|
|
453
|
+
return `S.object(s => {\n` + fields$2 + `\n })`;
|
|
454
|
+
case "Reference" :
|
|
455
|
+
let ref = irType._0;
|
|
456
|
+
let refName = ref.includes("/") ? Stdlib_Option.getOr(ref.split("/")[ref.split("/").length - 1 | 0], "") : ref;
|
|
457
|
+
let selfName = ctx.selfRefName;
|
|
458
|
+
let isSelfRef = selfName !== undefined ? refName === selfName : false;
|
|
459
|
+
if (isSelfRef) {
|
|
460
|
+
return "schema";
|
|
461
|
+
}
|
|
462
|
+
let available = ctx.availableSchemas;
|
|
463
|
+
let schemaPath = available !== undefined ? (
|
|
464
|
+
available.includes(refName) ? JsConvertCase.toPascalCase(refName) + `.schema` : `ComponentSchemas.` + JsConvertCase.toPascalCase(refName) + `.schema`
|
|
465
|
+
) : Stdlib_Option.getOr(ReferenceResolver.refToSchemaPath(ctx.insideComponentSchemas, ctx.modulePrefix, ref), "S.json");
|
|
466
|
+
if (schemaPath === "S.json") {
|
|
467
|
+
GenerationContext.addWarning(ctx, {
|
|
468
|
+
TAG: "FallbackToJson",
|
|
469
|
+
reason: `Unresolved ref: ` + ref,
|
|
470
|
+
context: {
|
|
471
|
+
path: ctx.path,
|
|
472
|
+
operation: "gen ref",
|
|
473
|
+
schema: undefined
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
return schemaPath;
|
|
478
|
+
case "Option" :
|
|
479
|
+
return `S.nullableAsOption(` + recurse(irType._0) + `)`;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function generateSchema(depthOpt, pathOpt, insideComponentSchemasOpt, availableSchemas, modulePrefixOpt, irType) {
|
|
485
|
+
let depth = depthOpt !== undefined ? depthOpt : 0;
|
|
486
|
+
let path = pathOpt !== undefined ? pathOpt : "";
|
|
487
|
+
let insideComponentSchemas = insideComponentSchemasOpt !== undefined ? insideComponentSchemasOpt : false;
|
|
488
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
489
|
+
let ctx = GenerationContext.make(path, insideComponentSchemas, availableSchemas, modulePrefix, undefined, undefined);
|
|
490
|
+
return [
|
|
491
|
+
generateSchemaWithContext(ctx, depth, undefined, irType),
|
|
492
|
+
ctx.warnings
|
|
493
|
+
];
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function generateNamedSchema(namedSchema, insideComponentSchemasOpt, availableSchemas, modulePrefixOpt, extractedTypesOpt) {
|
|
497
|
+
let insideComponentSchemas = insideComponentSchemasOpt !== undefined ? insideComponentSchemasOpt : false;
|
|
498
|
+
let modulePrefix = modulePrefixOpt !== undefined ? modulePrefixOpt : "";
|
|
499
|
+
let extractedTypes = extractedTypesOpt !== undefined ? extractedTypesOpt : [];
|
|
500
|
+
let ctx = GenerationContext.make(`schema.` + namedSchema.name, insideComponentSchemas, availableSchemas, modulePrefix, undefined, undefined);
|
|
501
|
+
let d = namedSchema.description;
|
|
502
|
+
let doc = d !== undefined ? CodegenUtils.generateDocComment(undefined, d, undefined) : "";
|
|
503
|
+
let extractedTypeMap = extractedTypes.length !== 0 ? extractedTypes : undefined;
|
|
504
|
+
let mainSchema = generateSchemaWithContext(ctx, 0, extractedTypeMap, namedSchema.type_);
|
|
505
|
+
let extractedDefs = extractedTypes.map(param => {
|
|
506
|
+
let typeName = param.typeName;
|
|
507
|
+
let auxCtx = GenerationContext.make(`schema.` + typeName, insideComponentSchemas, availableSchemas, modulePrefix, undefined, undefined);
|
|
508
|
+
let filteredMap = extractedTypes.filter(param => param.typeName !== typeName);
|
|
509
|
+
let auxExtractedTypeMap = filteredMap.length !== 0 ? filteredMap : undefined;
|
|
510
|
+
let auxSchema = generateSchemaWithContext(auxCtx, 0, auxExtractedTypeMap, param.irType);
|
|
511
|
+
return `let ` + typeName + `Schema = ` + auxSchema;
|
|
512
|
+
});
|
|
513
|
+
let allDefs = extractedDefs.concat([doc + `let ` + namedSchema.name + `Schema = ` + mainSchema]);
|
|
514
|
+
return [
|
|
515
|
+
allDefs.join("\n\n"),
|
|
516
|
+
ctx.warnings
|
|
517
|
+
];
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function generateAllSchemas(context) {
|
|
521
|
+
let warnings = [];
|
|
522
|
+
let schemas = Object.values(context.schemas).toSorted((a, b) => Primitive_string.compare(a.name, b.name)).map(s => {
|
|
523
|
+
let match = generateNamedSchema(s, undefined, undefined, undefined, undefined);
|
|
524
|
+
warnings.push(...match[1]);
|
|
525
|
+
return match[0];
|
|
526
|
+
});
|
|
527
|
+
return [
|
|
528
|
+
schemas,
|
|
529
|
+
warnings
|
|
530
|
+
];
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
let addWarning = GenerationContext.addWarning;
|
|
534
|
+
|
|
535
|
+
export {
|
|
536
|
+
addWarning,
|
|
537
|
+
applyConstraints,
|
|
538
|
+
generateSchemaWithContext,
|
|
539
|
+
generateSchema,
|
|
540
|
+
generateNamedSchema,
|
|
541
|
+
generateAllSchemas,
|
|
542
|
+
}
|
|
543
|
+
/* CodegenUtils Not a pure module */
|