@f3liz/rescript-autogen-openapi 0.1.7 → 0.3.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.

Potentially problematic release.


This version of @f3liz/rescript-autogen-openapi might be problematic. Click here for more details.

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