osury 1.0.1 → 1.2.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/dist/osury.mjs ADDED
@@ -0,0 +1,4041 @@
1
+ #!/usr/bin/env node
2
+
3
+ // node_modules/@rescript/runtime/lib/es6/Primitive_option.js
4
+ function some(x) {
5
+ if (x === void 0) {
6
+ return {
7
+ BS_PRIVATE_NESTED_SOME_NONE: 0
8
+ };
9
+ } else if (x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
10
+ return {
11
+ BS_PRIVATE_NESTED_SOME_NONE: x.BS_PRIVATE_NESTED_SOME_NONE + 1 | 0
12
+ };
13
+ } else {
14
+ return x;
15
+ }
16
+ }
17
+ function valFromOption(x) {
18
+ if (x === null || x.BS_PRIVATE_NESTED_SOME_NONE === void 0) {
19
+ return x;
20
+ }
21
+ let depth = x.BS_PRIVATE_NESTED_SOME_NONE;
22
+ if (depth === 0) {
23
+ return;
24
+ } else {
25
+ return {
26
+ BS_PRIVATE_NESTED_SOME_NONE: depth - 1 | 0
27
+ };
28
+ }
29
+ }
30
+
31
+ // src/Errors.mjs
32
+ function makeLocation(pathOpt, lineOpt, columnOpt, param) {
33
+ let path2 = pathOpt !== void 0 ? pathOpt : [];
34
+ let line = lineOpt !== void 0 ? valFromOption(lineOpt) : void 0;
35
+ let column = columnOpt !== void 0 ? valFromOption(columnOpt) : void 0;
36
+ return {
37
+ path: path2,
38
+ line,
39
+ column
40
+ };
41
+ }
42
+ function makeError(kind, pathOpt, hintOpt, param) {
43
+ let path2 = pathOpt !== void 0 ? pathOpt : [];
44
+ let hint = hintOpt !== void 0 ? valFromOption(hintOpt) : void 0;
45
+ return {
46
+ kind,
47
+ location: makeLocation(path2, void 0, void 0, void 0),
48
+ hint
49
+ };
50
+ }
51
+ function unknownType(value, pathOpt, hintOpt, param) {
52
+ let path2 = pathOpt !== void 0 ? pathOpt : [];
53
+ let hint = hintOpt !== void 0 ? valFromOption(hintOpt) : void 0;
54
+ return makeError({
55
+ TAG: "UnknownType",
56
+ _0: value
57
+ }, path2, some(hint), void 0);
58
+ }
59
+ function missingField(field, pathOpt, hintOpt, param) {
60
+ let path2 = pathOpt !== void 0 ? pathOpt : [];
61
+ let hint = hintOpt !== void 0 ? valFromOption(hintOpt) : void 0;
62
+ return makeError({
63
+ TAG: "MissingRequiredField",
64
+ _0: field
65
+ }, path2, some(hint), void 0);
66
+ }
67
+
68
+ // node_modules/@rescript/core/src/Core__Array.mjs
69
+ function reduce(arr, init, f) {
70
+ return arr.reduce(f, init);
71
+ }
72
+ function filterMap(a, f) {
73
+ let l = a.length;
74
+ let r = new Array(l);
75
+ let j = 0;
76
+ for (let i = 0; i < l; ++i) {
77
+ let v = a[i];
78
+ let v$1 = f(v);
79
+ if (v$1 !== void 0) {
80
+ r[j] = valFromOption(v$1);
81
+ j = j + 1 | 0;
82
+ }
83
+ }
84
+ r.length = j;
85
+ return r;
86
+ }
87
+ function findMap(arr, f) {
88
+ let _i = 0;
89
+ while (true) {
90
+ let i = _i;
91
+ if (i === arr.length) {
92
+ return;
93
+ }
94
+ let r = f(arr[i]);
95
+ if (r !== void 0) {
96
+ return r;
97
+ }
98
+ _i = i + 1 | 0;
99
+ continue;
100
+ }
101
+ ;
102
+ }
103
+
104
+ // node_modules/@rescript/core/src/Core__Option.mjs
105
+ function mapOr(opt, $$default, f) {
106
+ if (opt !== void 0) {
107
+ return f(valFromOption(opt));
108
+ } else {
109
+ return $$default;
110
+ }
111
+ }
112
+ function getOr(opt, $$default) {
113
+ if (opt !== void 0) {
114
+ return valFromOption(opt);
115
+ } else {
116
+ return $$default;
117
+ }
118
+ }
119
+ function isSome(x) {
120
+ return x !== void 0;
121
+ }
122
+ function isNone(x) {
123
+ return x === void 0;
124
+ }
125
+
126
+ // src/Schema.mjs
127
+ function isNullType(json) {
128
+ if (typeof json !== "object" || json === null || Array.isArray(json)) {
129
+ return false;
130
+ }
131
+ let match = json["type"];
132
+ return match === "null";
133
+ }
134
+ function hasDefault(json) {
135
+ if (typeof json === "object" && json !== null && !Array.isArray(json)) {
136
+ return isSome(json["default"]);
137
+ } else {
138
+ return false;
139
+ }
140
+ }
141
+ function extractRefName(refPath) {
142
+ let parts = refPath.split("/");
143
+ return getOr(parts[parts.length - 1 | 0], refPath);
144
+ }
145
+ function parseEnumValues(arr) {
146
+ let values = filterMap(arr, (item) => {
147
+ if (typeof item === "string") {
148
+ return item;
149
+ }
150
+ });
151
+ if (values.length === arr.length) {
152
+ return values;
153
+ }
154
+ }
155
+ function extractTagFromProperty(dict, propertyName) {
156
+ let match = dict[propertyName];
157
+ if (match === void 0) {
158
+ return;
159
+ }
160
+ if (typeof match !== "object" || match === null || Array.isArray(match)) {
161
+ return;
162
+ }
163
+ let match$1 = match["const"];
164
+ if (typeof match$1 === "string") {
165
+ return match$1;
166
+ }
167
+ }
168
+ function extractDiscriminatorPropertyName(dict) {
169
+ let match = dict["discriminator"];
170
+ if (match === void 0) {
171
+ return;
172
+ }
173
+ if (typeof match !== "object" || match === null || Array.isArray(match)) {
174
+ return;
175
+ }
176
+ let match$1 = match["propertyName"];
177
+ if (typeof match$1 === "string") {
178
+ return match$1;
179
+ }
180
+ }
181
+ function parseSchema(json) {
182
+ if (typeof json === "object" && json !== null && !Array.isArray(json)) {
183
+ return parseObject(json);
184
+ }
185
+ return {
186
+ TAG: "Error",
187
+ _0: [makeError({
188
+ TAG: "InvalidJson",
189
+ _0: "expected object"
190
+ }, void 0, void 0, void 0)]
191
+ };
192
+ }
193
+ function parsePrimitiveType(dict) {
194
+ let match = dict["type"];
195
+ if (match !== void 0) {
196
+ if (Array.isArray(match)) {
197
+ let typeStrings = filterMap(match, (t) => {
198
+ if (typeof t === "string") {
199
+ return t;
200
+ }
201
+ });
202
+ let hasNull = typeStrings.includes("null");
203
+ let nonNullTypes = typeStrings.filter((t) => t !== "null");
204
+ if (!hasNull) {
205
+ return {
206
+ TAG: "Error",
207
+ _0: [makeError({
208
+ TAG: "UnsupportedFeature",
209
+ _0: "type array without null"
210
+ }, void 0, void 0, void 0)]
211
+ };
212
+ }
213
+ if (nonNullTypes.length !== 1) {
214
+ return {
215
+ TAG: "Error",
216
+ _0: [makeError({
217
+ TAG: "InvalidJson",
218
+ _0: "type array must have exactly one non-null type"
219
+ }, void 0, void 0, void 0)]
220
+ };
221
+ }
222
+ let nonNullType = nonNullTypes[0];
223
+ let newDict = Object.fromEntries(Object.entries(dict).map((param) => {
224
+ let k = param[0];
225
+ if (k === "type") {
226
+ return [
227
+ k,
228
+ nonNullType
229
+ ];
230
+ } else {
231
+ return [
232
+ k,
233
+ param[1]
234
+ ];
235
+ }
236
+ }));
237
+ let inner = parsePrimitiveType(newDict);
238
+ if (inner.TAG === "Ok") {
239
+ return {
240
+ TAG: "Ok",
241
+ _0: {
242
+ _tag: "Nullable",
243
+ _0: inner._0
244
+ }
245
+ };
246
+ } else {
247
+ return {
248
+ TAG: "Error",
249
+ _0: inner._0
250
+ };
251
+ }
252
+ }
253
+ switch (typeof match) {
254
+ case "string":
255
+ switch (match) {
256
+ case "array":
257
+ return parseArrayType(dict);
258
+ case "boolean":
259
+ return {
260
+ TAG: "Ok",
261
+ _0: "Boolean"
262
+ };
263
+ case "integer":
264
+ return {
265
+ TAG: "Ok",
266
+ _0: "Integer"
267
+ };
268
+ case "null":
269
+ return {
270
+ TAG: "Ok",
271
+ _0: "Null"
272
+ };
273
+ case "number":
274
+ return {
275
+ TAG: "Ok",
276
+ _0: "Number"
277
+ };
278
+ case "object":
279
+ return parseObjectType(dict);
280
+ case "string":
281
+ let match$1 = dict["const"];
282
+ let exit = 0;
283
+ if (match$1 !== void 0) {
284
+ if (typeof match$1 === "string") {
285
+ return {
286
+ TAG: "Ok",
287
+ _0: {
288
+ _tag: "Enum",
289
+ _0: [match$1]
290
+ }
291
+ };
292
+ }
293
+ exit = 2;
294
+ } else {
295
+ exit = 2;
296
+ }
297
+ if (exit === 2) {
298
+ let match$2 = dict["enum"];
299
+ if (match$2 === void 0) {
300
+ return {
301
+ TAG: "Ok",
302
+ _0: "String"
303
+ };
304
+ }
305
+ let exit$1 = 0;
306
+ if (Array.isArray(match$2)) {
307
+ let values = parseEnumValues(match$2);
308
+ if (values !== void 0) {
309
+ return {
310
+ TAG: "Ok",
311
+ _0: {
312
+ _tag: "Enum",
313
+ _0: values
314
+ }
315
+ };
316
+ } else {
317
+ return {
318
+ TAG: "Error",
319
+ _0: [makeError({
320
+ TAG: "InvalidJson",
321
+ _0: "enum values must be strings"
322
+ }, void 0, void 0, void 0)]
323
+ };
324
+ }
325
+ }
326
+ exit$1 = 3;
327
+ if (exit$1 === 3) {
328
+ return {
329
+ TAG: "Error",
330
+ _0: [makeError({
331
+ TAG: "InvalidJson",
332
+ _0: "enum must be an array"
333
+ }, void 0, void 0, void 0)]
334
+ };
335
+ }
336
+ }
337
+ break;
338
+ default:
339
+ return {
340
+ TAG: "Error",
341
+ _0: [unknownType(match, void 0, void 0, void 0)]
342
+ };
343
+ }
344
+ break;
345
+ }
346
+ return {
347
+ TAG: "Error",
348
+ _0: [makeError({
349
+ TAG: "InvalidJson",
350
+ _0: "type must be a string or array"
351
+ }, void 0, void 0, void 0)]
352
+ };
353
+ }
354
+ let match$3 = dict["properties"];
355
+ if (match$3 !== void 0) {
356
+ return parseObjectType(dict);
357
+ } else {
358
+ return {
359
+ TAG: "Ok",
360
+ _0: "Unknown"
361
+ };
362
+ }
363
+ }
364
+ function parseArrayType(dict) {
365
+ let itemSchema = dict["items"];
366
+ if (itemSchema === void 0) {
367
+ return {
368
+ TAG: "Error",
369
+ _0: [missingField("items", void 0, "array type requires items schema", void 0)]
370
+ };
371
+ }
372
+ let itemType = parseSchema(itemSchema);
373
+ if (itemType.TAG === "Ok") {
374
+ return {
375
+ TAG: "Ok",
376
+ _0: {
377
+ _tag: "Array",
378
+ _0: itemType._0
379
+ }
380
+ };
381
+ } else {
382
+ return {
383
+ TAG: "Error",
384
+ _0: itemType._0
385
+ };
386
+ }
387
+ }
388
+ function parseAnyOf(items) {
389
+ let hasNull = items.some(isNullType);
390
+ let nonNullItems = items.filter((item) => !isNullType(item));
391
+ if (hasNull && nonNullItems.length === 1) {
392
+ let match = nonNullItems[0];
393
+ if (match === void 0) {
394
+ return {
395
+ TAG: "Error",
396
+ _0: [makeError({
397
+ TAG: "InvalidJson",
398
+ _0: "anyOf with only null types"
399
+ }, void 0, void 0, void 0)]
400
+ };
401
+ }
402
+ if (typeof match === "object" && match !== null && !Array.isArray(match)) {
403
+ let innerType = parseObject(match);
404
+ if (innerType.TAG === "Ok") {
405
+ return {
406
+ TAG: "Ok",
407
+ _0: {
408
+ _tag: "Nullable",
409
+ _0: innerType._0
410
+ }
411
+ };
412
+ } else {
413
+ return {
414
+ TAG: "Error",
415
+ _0: innerType._0
416
+ };
417
+ }
418
+ }
419
+ return {
420
+ TAG: "Error",
421
+ _0: [makeError({
422
+ TAG: "InvalidJson",
423
+ _0: "anyOf item must be object"
424
+ }, void 0, void 0, void 0)]
425
+ };
426
+ }
427
+ if (!hasNull && nonNullItems.length >= 2) {
428
+ let results = nonNullItems.map(parseSchema);
429
+ let errors = filterMap(results, (r) => {
430
+ if (r.TAG === "Ok") {
431
+ return;
432
+ } else {
433
+ return r._0;
434
+ }
435
+ }).flat();
436
+ if (errors.length > 0) {
437
+ return {
438
+ TAG: "Error",
439
+ _0: errors
440
+ };
441
+ }
442
+ let types = filterMap(results, (r) => {
443
+ if (r.TAG === "Ok") {
444
+ return r._0;
445
+ }
446
+ });
447
+ return {
448
+ TAG: "Ok",
449
+ _0: {
450
+ _tag: "Union",
451
+ _0: types
452
+ }
453
+ };
454
+ }
455
+ if (!(hasNull && nonNullItems.length >= 2)) {
456
+ return {
457
+ TAG: "Error",
458
+ _0: [makeError({
459
+ TAG: "InvalidJson",
460
+ _0: "anyOf must have at least 2 items"
461
+ }, void 0, void 0, void 0)]
462
+ };
463
+ }
464
+ let results$1 = nonNullItems.map(parseSchema);
465
+ let errors$1 = filterMap(results$1, (r) => {
466
+ if (r.TAG === "Ok") {
467
+ return;
468
+ } else {
469
+ return r._0;
470
+ }
471
+ }).flat();
472
+ if (errors$1.length > 0) {
473
+ return {
474
+ TAG: "Error",
475
+ _0: errors$1
476
+ };
477
+ }
478
+ let types$1 = filterMap(results$1, (r) => {
479
+ if (r.TAG === "Ok") {
480
+ return r._0;
481
+ }
482
+ });
483
+ return {
484
+ TAG: "Ok",
485
+ _0: {
486
+ _tag: "Nullable",
487
+ _0: {
488
+ _tag: "Union",
489
+ _0: types$1
490
+ }
491
+ }
492
+ };
493
+ }
494
+ function parseObjectType(dict) {
495
+ let valueSchema = dict["additionalProperties"];
496
+ let exit = 0;
497
+ if (valueSchema !== void 0) {
498
+ switch (typeof valueSchema) {
499
+ case "boolean":
500
+ if (valueSchema) {
501
+ return {
502
+ TAG: "Ok",
503
+ _0: {
504
+ _tag: "Dict",
505
+ _0: "String"
506
+ }
507
+ };
508
+ }
509
+ exit = 1;
510
+ break;
511
+ case "object":
512
+ let valueType = parseSchema(valueSchema);
513
+ if (valueType.TAG === "Ok") {
514
+ return {
515
+ TAG: "Ok",
516
+ _0: {
517
+ _tag: "Dict",
518
+ _0: valueType._0
519
+ }
520
+ };
521
+ } else {
522
+ return {
523
+ TAG: "Error",
524
+ _0: valueType._0
525
+ };
526
+ }
527
+ default:
528
+ exit = 1;
529
+ }
530
+ } else {
531
+ exit = 1;
532
+ }
533
+ if (exit === 1) {
534
+ let match = dict["required"];
535
+ let requiredFields = match !== void 0 ? Array.isArray(match) ? filterMap(match, (item) => {
536
+ if (typeof item === "string") {
537
+ return item;
538
+ }
539
+ }) : [] : [];
540
+ let match$1 = dict["properties"];
541
+ if (match$1 === void 0) {
542
+ return {
543
+ TAG: "Ok",
544
+ _0: {
545
+ _tag: "Object",
546
+ _0: []
547
+ }
548
+ };
549
+ }
550
+ let exit$1 = 0;
551
+ if (typeof match$1 === "object" && match$1 !== null && !Array.isArray(match$1)) {
552
+ let entries = Object.entries(match$1).filter((param) => param[0] !== "_tag");
553
+ let results = entries.map((param) => {
554
+ let propSchema = param[1];
555
+ let name = param[0];
556
+ let propType = parseSchema(propSchema);
557
+ if (propType.TAG === "Ok") {
558
+ return {
559
+ TAG: "Ok",
560
+ _0: {
561
+ name,
562
+ type: propType._0,
563
+ required: requiredFields.includes(name) || hasDefault(propSchema)
564
+ }
565
+ };
566
+ } else {
567
+ return {
568
+ TAG: "Error",
569
+ _0: propType._0
570
+ };
571
+ }
572
+ });
573
+ let errors = filterMap(results, (r) => {
574
+ if (r.TAG === "Ok") {
575
+ return;
576
+ } else {
577
+ return r._0;
578
+ }
579
+ }).flat();
580
+ if (errors.length > 0) {
581
+ return {
582
+ TAG: "Error",
583
+ _0: errors
584
+ };
585
+ }
586
+ let fields = filterMap(results, (r) => {
587
+ if (r.TAG === "Ok") {
588
+ return r._0;
589
+ }
590
+ });
591
+ return {
592
+ TAG: "Ok",
593
+ _0: {
594
+ _tag: "Object",
595
+ _0: fields
596
+ }
597
+ };
598
+ }
599
+ exit$1 = 2;
600
+ if (exit$1 === 2) {
601
+ return {
602
+ TAG: "Error",
603
+ _0: [makeError({
604
+ TAG: "InvalidJson",
605
+ _0: "properties must be an object"
606
+ }, void 0, void 0, void 0)]
607
+ };
608
+ }
609
+ }
610
+ }
611
+ function parseAllOf(items) {
612
+ let results = items.map(parseSchema);
613
+ let errors = filterMap(results, (r) => {
614
+ if (r.TAG === "Ok") {
615
+ return;
616
+ } else {
617
+ return r._0;
618
+ }
619
+ }).flat();
620
+ if (errors.length > 0) {
621
+ return {
622
+ TAG: "Error",
623
+ _0: errors
624
+ };
625
+ }
626
+ let allFields = filterMap(results, (r) => {
627
+ if (r.TAG !== "Ok") {
628
+ return;
629
+ }
630
+ let fields = r._0;
631
+ if (typeof fields !== "object" || fields._tag !== "Object") {
632
+ return;
633
+ } else {
634
+ return fields._0;
635
+ }
636
+ }).flat();
637
+ return {
638
+ TAG: "Ok",
639
+ _0: {
640
+ _tag: "Object",
641
+ _0: allFields
642
+ }
643
+ };
644
+ }
645
+ function parseOneOf(items, discriminatorPropertyNameOpt) {
646
+ let discriminatorPropertyName = discriminatorPropertyNameOpt !== void 0 ? valFromOption(discriminatorPropertyNameOpt) : void 0;
647
+ let propName = getOr(discriminatorPropertyName, "_tag");
648
+ let caseResults = items.map((item) => {
649
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
650
+ let match = item["$ref"];
651
+ let exit = 0;
652
+ if (match !== void 0) {
653
+ if (typeof match === "string") {
654
+ let name = extractRefName(match);
655
+ return {
656
+ TAG: "Ok",
657
+ _0: {
658
+ _tag: name,
659
+ payload: {
660
+ _tag: "Ref",
661
+ _0: name
662
+ }
663
+ }
664
+ };
665
+ }
666
+ exit = 2;
667
+ } else {
668
+ exit = 2;
669
+ }
670
+ if (exit === 2) {
671
+ let match$1 = item["properties"];
672
+ let exit$1 = 0;
673
+ if (match$1 !== void 0) {
674
+ if (typeof match$1 === "object" && match$1 !== null && !Array.isArray(match$1)) {
675
+ let tag = extractTagFromProperty(match$1, propName);
676
+ if (tag === void 0) {
677
+ return {
678
+ TAG: "Error",
679
+ _0: [makeError({
680
+ TAG: "MissingRequiredField",
681
+ _0: propName + " with const"
682
+ }, void 0, void 0, void 0)]
683
+ };
684
+ }
685
+ let match$2 = item["required"];
686
+ let requiredFields = match$2 !== void 0 ? Array.isArray(match$2) ? filterMap(match$2, (i) => {
687
+ if (typeof i === "string") {
688
+ return i;
689
+ }
690
+ }) : [] : [];
691
+ let entries = Object.entries(match$1).filter((param) => param[0] !== propName);
692
+ let fieldResults = entries.map((param) => {
693
+ let name = param[0];
694
+ let propType = parseSchema(param[1]);
695
+ if (propType.TAG === "Ok") {
696
+ return {
697
+ TAG: "Ok",
698
+ _0: {
699
+ name,
700
+ type: propType._0,
701
+ required: requiredFields.includes(name)
702
+ }
703
+ };
704
+ } else {
705
+ return {
706
+ TAG: "Error",
707
+ _0: propType._0
708
+ };
709
+ }
710
+ });
711
+ let errors2 = filterMap(fieldResults, (r) => {
712
+ if (r.TAG === "Ok") {
713
+ return;
714
+ } else {
715
+ return r._0;
716
+ }
717
+ }).flat();
718
+ if (errors2.length > 0) {
719
+ return {
720
+ TAG: "Error",
721
+ _0: errors2
722
+ };
723
+ }
724
+ let fields = filterMap(fieldResults, (r) => {
725
+ if (r.TAG === "Ok") {
726
+ return r._0;
727
+ }
728
+ });
729
+ return {
730
+ TAG: "Ok",
731
+ _0: {
732
+ _tag: tag,
733
+ payload: {
734
+ _tag: "Object",
735
+ _0: fields
736
+ }
737
+ }
738
+ };
739
+ }
740
+ exit$1 = 3;
741
+ } else {
742
+ exit$1 = 3;
743
+ }
744
+ if (exit$1 === 3) {
745
+ return {
746
+ TAG: "Error",
747
+ _0: [makeError({
748
+ TAG: "InvalidJson",
749
+ _0: "oneOf item must have properties"
750
+ }, void 0, void 0, void 0)]
751
+ };
752
+ }
753
+ }
754
+ }
755
+ return {
756
+ TAG: "Error",
757
+ _0: [makeError({
758
+ TAG: "InvalidJson",
759
+ _0: "oneOf item must be object"
760
+ }, void 0, void 0, void 0)]
761
+ };
762
+ });
763
+ let errors = filterMap(caseResults, (r) => {
764
+ if (r.TAG === "Ok") {
765
+ return;
766
+ } else {
767
+ return r._0;
768
+ }
769
+ }).flat();
770
+ if (errors.length > 0) {
771
+ return {
772
+ TAG: "Error",
773
+ _0: errors
774
+ };
775
+ }
776
+ let cases = filterMap(caseResults, (r) => {
777
+ if (r.TAG === "Ok") {
778
+ return r._0;
779
+ }
780
+ });
781
+ return {
782
+ TAG: "Ok",
783
+ _0: {
784
+ _tag: "PolyVariant",
785
+ _0: cases
786
+ }
787
+ };
788
+ }
789
+ function applyNullable(dict, result) {
790
+ let match = dict["nullable"];
791
+ if (match === void 0) {
792
+ return result;
793
+ }
794
+ if (typeof match !== "boolean") {
795
+ return result;
796
+ }
797
+ if (!match) {
798
+ return result;
799
+ }
800
+ if (result.TAG !== "Ok") {
801
+ return result;
802
+ }
803
+ let t = result._0;
804
+ if (typeof t !== "object" || t._tag !== "Nullable") {
805
+ return {
806
+ TAG: "Ok",
807
+ _0: {
808
+ _tag: "Nullable",
809
+ _0: t
810
+ }
811
+ };
812
+ } else {
813
+ return {
814
+ TAG: "Ok",
815
+ _0: t
816
+ };
817
+ }
818
+ }
819
+ function parseObject(dict) {
820
+ let match = dict["$ref"];
821
+ if (match !== void 0) {
822
+ if (typeof match === "string") {
823
+ return applyNullable(dict, {
824
+ TAG: "Ok",
825
+ _0: {
826
+ _tag: "Ref",
827
+ _0: extractRefName(match)
828
+ }
829
+ });
830
+ }
831
+ return {
832
+ TAG: "Error",
833
+ _0: [makeError({
834
+ TAG: "InvalidJson",
835
+ _0: "$ref must be a string"
836
+ }, void 0, void 0, void 0)]
837
+ };
838
+ }
839
+ let match$1 = dict["oneOf"];
840
+ if (match$1 !== void 0) {
841
+ if (Array.isArray(match$1)) {
842
+ let hasNull = match$1.some(isNullType);
843
+ let nonNullItems = match$1.filter((item) => !isNullType(item));
844
+ if (hasNull && nonNullItems.length === 1) {
845
+ let match$2 = nonNullItems[0];
846
+ if (match$2 === void 0) {
847
+ return {
848
+ TAG: "Error",
849
+ _0: [makeError({
850
+ TAG: "InvalidJson",
851
+ _0: "oneOf with only null types"
852
+ }, void 0, void 0, void 0)]
853
+ };
854
+ }
855
+ let exit = 0;
856
+ if (typeof match$2 === "object" && match$2 !== null && !Array.isArray(match$2)) {
857
+ let innerType = parseObject(match$2);
858
+ if (innerType.TAG === "Ok") {
859
+ return {
860
+ TAG: "Ok",
861
+ _0: {
862
+ _tag: "Nullable",
863
+ _0: innerType._0
864
+ }
865
+ };
866
+ } else {
867
+ return {
868
+ TAG: "Error",
869
+ _0: innerType._0
870
+ };
871
+ }
872
+ }
873
+ exit = 2;
874
+ if (exit === 2) {
875
+ return {
876
+ TAG: "Error",
877
+ _0: [makeError({
878
+ TAG: "InvalidJson",
879
+ _0: "oneOf item must be object"
880
+ }, void 0, void 0, void 0)]
881
+ };
882
+ }
883
+ } else {
884
+ if (hasNull && nonNullItems.length >= 2) {
885
+ let discriminatorPropName = extractDiscriminatorPropertyName(dict);
886
+ let inner = parseOneOf(nonNullItems, some(discriminatorPropName));
887
+ if (inner.TAG === "Ok") {
888
+ return {
889
+ TAG: "Ok",
890
+ _0: {
891
+ _tag: "Nullable",
892
+ _0: inner._0
893
+ }
894
+ };
895
+ } else {
896
+ return {
897
+ TAG: "Error",
898
+ _0: inner._0
899
+ };
900
+ }
901
+ }
902
+ let discriminatorPropName$1 = extractDiscriminatorPropertyName(dict);
903
+ return parseOneOf(match$1, some(discriminatorPropName$1));
904
+ }
905
+ }
906
+ return {
907
+ TAG: "Error",
908
+ _0: [makeError({
909
+ TAG: "InvalidJson",
910
+ _0: "oneOf must be an array"
911
+ }, void 0, void 0, void 0)]
912
+ };
913
+ }
914
+ let match$3 = dict["allOf"];
915
+ if (match$3 !== void 0) {
916
+ if (Array.isArray(match$3)) {
917
+ return parseAllOf(match$3);
918
+ }
919
+ return {
920
+ TAG: "Error",
921
+ _0: [makeError({
922
+ TAG: "InvalidJson",
923
+ _0: "allOf must be an array"
924
+ }, void 0, void 0, void 0)]
925
+ };
926
+ }
927
+ let match$4 = dict["anyOf"];
928
+ if (match$4 === void 0) {
929
+ return applyNullable(dict, parsePrimitiveType(dict));
930
+ }
931
+ if (Array.isArray(match$4)) {
932
+ return parseAnyOf(match$4);
933
+ }
934
+ return {
935
+ TAG: "Error",
936
+ _0: [makeError({
937
+ TAG: "InvalidJson",
938
+ _0: "anyOf must be an array"
939
+ }, void 0, void 0, void 0)]
940
+ };
941
+ }
942
+ var parse = parseSchema;
943
+
944
+ // src/OpenAPIParser.mjs
945
+ function pathToName(path2) {
946
+ return path2.split("/").filter((s) => {
947
+ if (s !== "") {
948
+ return !s.startsWith("{");
949
+ } else {
950
+ return false;
951
+ }
952
+ }).map((segment) => segment.split("-").map((part) => {
953
+ let first = part.charAt(0).toUpperCase();
954
+ let rest = part.slice(1);
955
+ return first + rest;
956
+ }).join("")).join("");
957
+ }
958
+ function ucFirst(s) {
959
+ let first = s.charAt(0).toUpperCase();
960
+ let rest = s.slice(1);
961
+ return first + rest;
962
+ }
963
+ function parsePathResponses(pathsJson) {
964
+ if (typeof pathsJson !== "object" || pathsJson === null || Array.isArray(pathsJson)) {
965
+ return {
966
+ TAG: "Ok",
967
+ _0: []
968
+ };
969
+ }
970
+ let results = Object.entries(pathsJson).flatMap((param) => {
971
+ let methodsJson = param[1];
972
+ let path2 = param[0];
973
+ if (typeof methodsJson === "object" && methodsJson !== null && !Array.isArray(methodsJson)) {
974
+ return filterMap(Object.entries(methodsJson), (param2) => {
975
+ let opJson = param2[1];
976
+ let method = param2[0];
977
+ let httpMethods = [
978
+ "get",
979
+ "post",
980
+ "put",
981
+ "patch",
982
+ "delete"
983
+ ];
984
+ if (!httpMethods.includes(method)) {
985
+ return;
986
+ }
987
+ if (typeof opJson !== "object" || opJson === null || Array.isArray(opJson)) {
988
+ return;
989
+ }
990
+ let match = opJson["responses"];
991
+ if (match === void 0) {
992
+ return;
993
+ }
994
+ if (typeof match !== "object" || match === null || Array.isArray(match)) {
995
+ return;
996
+ }
997
+ let r = match["200"];
998
+ let responseJson = r !== void 0 ? r : match["201"];
999
+ if (responseJson === void 0) {
1000
+ return;
1001
+ }
1002
+ if (typeof responseJson !== "object" || responseJson === null || Array.isArray(responseJson)) {
1003
+ return;
1004
+ }
1005
+ let match$1 = responseJson["content"];
1006
+ if (match$1 === void 0) {
1007
+ return;
1008
+ }
1009
+ if (typeof match$1 !== "object" || match$1 === null || Array.isArray(match$1)) {
1010
+ return;
1011
+ }
1012
+ let match$2 = match$1["application/json"];
1013
+ if (match$2 === void 0) {
1014
+ return;
1015
+ }
1016
+ if (typeof match$2 !== "object" || match$2 === null || Array.isArray(match$2)) {
1017
+ return;
1018
+ }
1019
+ let schemaJson = match$2["schema"];
1020
+ if (schemaJson === void 0) {
1021
+ return;
1022
+ }
1023
+ let name = ucFirst(method) + pathToName(path2) + "Response";
1024
+ let schemaType = parse(schemaJson);
1025
+ if (schemaType.TAG === "Ok") {
1026
+ return {
1027
+ TAG: "Ok",
1028
+ _0: {
1029
+ name,
1030
+ schema: schemaType._0,
1031
+ discriminatorTag: void 0,
1032
+ discriminatorPropertyName: void 0,
1033
+ fieldDiscriminators: void 0
1034
+ }
1035
+ };
1036
+ } else {
1037
+ return {
1038
+ TAG: "Error",
1039
+ _0: schemaType._0
1040
+ };
1041
+ }
1042
+ });
1043
+ } else {
1044
+ return [];
1045
+ }
1046
+ });
1047
+ let errors = filterMap(results, (r) => {
1048
+ if (r.TAG === "Ok") {
1049
+ return;
1050
+ } else {
1051
+ return r._0;
1052
+ }
1053
+ }).flat();
1054
+ if (errors.length > 0) {
1055
+ return {
1056
+ TAG: "Error",
1057
+ _0: errors
1058
+ };
1059
+ }
1060
+ let schemas = filterMap(results, (r) => {
1061
+ if (r.TAG === "Ok") {
1062
+ return r._0;
1063
+ }
1064
+ });
1065
+ return {
1066
+ TAG: "Ok",
1067
+ _0: schemas
1068
+ };
1069
+ }
1070
+ function extractDiscriminatorFromPair(items, discDict) {
1071
+ let match = discDict["propertyName"];
1072
+ if (match === void 0) {
1073
+ return;
1074
+ }
1075
+ if (typeof match !== "string") {
1076
+ return;
1077
+ }
1078
+ let memberNames = filterMap(items, (item) => {
1079
+ if (typeof item !== "object" || item === null || Array.isArray(item)) {
1080
+ return;
1081
+ }
1082
+ let match2 = item["$ref"];
1083
+ if (match2 === void 0) {
1084
+ return;
1085
+ }
1086
+ if (typeof match2 !== "string") {
1087
+ return;
1088
+ }
1089
+ let parts = match2.split("/");
1090
+ return parts[parts.length - 1 | 0];
1091
+ });
1092
+ if (memberNames.length < 2) {
1093
+ return;
1094
+ }
1095
+ let lcNames = memberNames.map((n) => {
1096
+ let first = n.charAt(0).toLowerCase();
1097
+ let rest = n.slice(1);
1098
+ return first + rest;
1099
+ });
1100
+ let firstName = getOr(lcNames[0], "unknown");
1101
+ let restNames = lcNames.slice(1);
1102
+ let unionName = firstName + restNames.map((n) => "Or" + ucFirst(n)).join("");
1103
+ return [
1104
+ unionName,
1105
+ match
1106
+ ];
1107
+ }
1108
+ function extractFieldDiscriminators(schemaJson) {
1109
+ let result = {};
1110
+ if (typeof schemaJson === "object" && schemaJson !== null && !Array.isArray(schemaJson)) {
1111
+ let match = schemaJson["properties"];
1112
+ if (typeof match === "object" && match !== null && !Array.isArray(match)) {
1113
+ Object.entries(match).forEach((param) => {
1114
+ let propJson = param[1];
1115
+ if (typeof propJson !== "object" || propJson === null || Array.isArray(propJson)) {
1116
+ return;
1117
+ }
1118
+ let match2 = propJson["anyOf"];
1119
+ let directItems;
1120
+ let exit = 0;
1121
+ if (Array.isArray(match2)) {
1122
+ directItems = match2;
1123
+ } else {
1124
+ exit = 1;
1125
+ }
1126
+ if (exit === 1) {
1127
+ let match$1 = propJson["oneOf"];
1128
+ directItems = Array.isArray(match$1) ? match$1 : void 0;
1129
+ }
1130
+ let match$2 = propJson["discriminator"];
1131
+ let exit$1 = 0;
1132
+ if (directItems !== void 0 && match$2 !== void 0) {
1133
+ if (typeof match$2 === "object" && match$2 !== null && !Array.isArray(match$2)) {
1134
+ let match$3 = extractDiscriminatorFromPair(directItems, match$2);
1135
+ if (match$3 !== void 0) {
1136
+ result[match$3[0]] = match$3[1];
1137
+ return;
1138
+ } else {
1139
+ return;
1140
+ }
1141
+ }
1142
+ exit$1 = 1;
1143
+ } else {
1144
+ exit$1 = 1;
1145
+ }
1146
+ if (exit$1 === 1) {
1147
+ let match$4 = propJson["items"];
1148
+ if (match$4 === void 0) {
1149
+ return;
1150
+ }
1151
+ if (typeof match$4 !== "object" || match$4 === null || Array.isArray(match$4)) {
1152
+ return;
1153
+ }
1154
+ let match$5 = match$4["anyOf"];
1155
+ let nestedItems;
1156
+ let exit$2 = 0;
1157
+ if (Array.isArray(match$5)) {
1158
+ nestedItems = match$5;
1159
+ } else {
1160
+ exit$2 = 2;
1161
+ }
1162
+ if (exit$2 === 2) {
1163
+ let match$6 = match$4["oneOf"];
1164
+ nestedItems = Array.isArray(match$6) ? match$6 : void 0;
1165
+ }
1166
+ let match$7 = match$4["discriminator"];
1167
+ if (nestedItems === void 0) {
1168
+ return;
1169
+ }
1170
+ if (match$7 === void 0) {
1171
+ return;
1172
+ }
1173
+ if (typeof match$7 !== "object" || match$7 === null || Array.isArray(match$7)) {
1174
+ return;
1175
+ }
1176
+ let match$8 = extractDiscriminatorFromPair(nestedItems, match$7);
1177
+ if (match$8 !== void 0) {
1178
+ result[match$8[0]] = match$8[1];
1179
+ return;
1180
+ } else {
1181
+ return;
1182
+ }
1183
+ }
1184
+ });
1185
+ }
1186
+ }
1187
+ return result;
1188
+ }
1189
+ function extractDiscriminatorPropertyName2(schemaJson) {
1190
+ if (typeof schemaJson !== "object" || schemaJson === null || Array.isArray(schemaJson)) {
1191
+ return;
1192
+ }
1193
+ let match = schemaJson["discriminator"];
1194
+ if (match === void 0) {
1195
+ return;
1196
+ }
1197
+ if (typeof match !== "object" || match === null || Array.isArray(match)) {
1198
+ return;
1199
+ }
1200
+ let match$1 = match["propertyName"];
1201
+ if (typeof match$1 === "string") {
1202
+ return match$1;
1203
+ }
1204
+ }
1205
+ function extractDiscriminatorTag(schemaJson) {
1206
+ if (typeof schemaJson !== "object" || schemaJson === null || Array.isArray(schemaJson)) {
1207
+ return;
1208
+ }
1209
+ let match = schemaJson["properties"];
1210
+ if (match === void 0) {
1211
+ return;
1212
+ }
1213
+ if (typeof match !== "object" || match === null || Array.isArray(match)) {
1214
+ return;
1215
+ }
1216
+ let match$1 = match["_tag"];
1217
+ if (match$1 === void 0) {
1218
+ return;
1219
+ }
1220
+ if (typeof match$1 !== "object" || match$1 === null || Array.isArray(match$1)) {
1221
+ return;
1222
+ }
1223
+ let match$2 = match$1["const"];
1224
+ if (typeof match$2 === "string") {
1225
+ return match$2;
1226
+ }
1227
+ }
1228
+ function parseComponentSchemas(componentsJson) {
1229
+ if (typeof componentsJson === "object" && componentsJson !== null && !Array.isArray(componentsJson)) {
1230
+ let match = componentsJson["schemas"];
1231
+ if (match === void 0) {
1232
+ return {
1233
+ TAG: "Ok",
1234
+ _0: []
1235
+ };
1236
+ }
1237
+ let exit = 0;
1238
+ if (typeof match === "object" && match !== null && !Array.isArray(match)) {
1239
+ let entries = Object.entries(match);
1240
+ let results = entries.map((param) => {
1241
+ let schemaJson = param[1];
1242
+ let discriminatorTag = extractDiscriminatorTag(schemaJson);
1243
+ let discriminatorPropertyName = extractDiscriminatorPropertyName2(schemaJson);
1244
+ let fieldDiscs = extractFieldDiscriminators(schemaJson);
1245
+ let fieldDiscriminators = Object.entries(fieldDiscs).length > 0 ? fieldDiscs : void 0;
1246
+ let schemaType = parse(schemaJson);
1247
+ if (schemaType.TAG === "Ok") {
1248
+ return {
1249
+ TAG: "Ok",
1250
+ _0: {
1251
+ name: param[0],
1252
+ schema: schemaType._0,
1253
+ discriminatorTag,
1254
+ discriminatorPropertyName,
1255
+ fieldDiscriminators
1256
+ }
1257
+ };
1258
+ } else {
1259
+ return {
1260
+ TAG: "Error",
1261
+ _0: schemaType._0
1262
+ };
1263
+ }
1264
+ });
1265
+ let errors = filterMap(results, (r) => {
1266
+ if (r.TAG === "Ok") {
1267
+ return;
1268
+ } else {
1269
+ return r._0;
1270
+ }
1271
+ }).flat();
1272
+ if (errors.length > 0) {
1273
+ return {
1274
+ TAG: "Error",
1275
+ _0: errors
1276
+ };
1277
+ }
1278
+ let schemas = filterMap(results, (r) => {
1279
+ if (r.TAG === "Ok") {
1280
+ return r._0;
1281
+ }
1282
+ });
1283
+ return {
1284
+ TAG: "Ok",
1285
+ _0: schemas
1286
+ };
1287
+ }
1288
+ exit = 2;
1289
+ if (exit === 2) {
1290
+ return {
1291
+ TAG: "Error",
1292
+ _0: [makeError({
1293
+ TAG: "InvalidJson",
1294
+ _0: "schemas must be an object"
1295
+ }, void 0, void 0, void 0)]
1296
+ };
1297
+ }
1298
+ }
1299
+ return {
1300
+ TAG: "Error",
1301
+ _0: [makeError({
1302
+ TAG: "InvalidJson",
1303
+ _0: "components must be an object"
1304
+ }, void 0, void 0, void 0)]
1305
+ };
1306
+ }
1307
+ function buildParamsObjectJson(params) {
1308
+ let properties = {};
1309
+ let required = [];
1310
+ params.forEach((param) => {
1311
+ if (typeof param !== "object" || param === null || Array.isArray(param)) {
1312
+ return;
1313
+ }
1314
+ let match = param["in"];
1315
+ let location = typeof match === "string" ? match : void 0;
1316
+ let isQueryOrPath;
1317
+ if (location !== void 0) {
1318
+ switch (location) {
1319
+ case "path":
1320
+ case "query":
1321
+ isQueryOrPath = true;
1322
+ break;
1323
+ default:
1324
+ isQueryOrPath = false;
1325
+ }
1326
+ } else {
1327
+ isQueryOrPath = false;
1328
+ }
1329
+ if (!isQueryOrPath) {
1330
+ return;
1331
+ }
1332
+ let match$1 = param["name"];
1333
+ let match$2 = param["schema"];
1334
+ if (match$1 === void 0) {
1335
+ return;
1336
+ }
1337
+ if (typeof match$1 !== "string") {
1338
+ return;
1339
+ }
1340
+ if (match$2 === void 0) {
1341
+ return;
1342
+ }
1343
+ let cleanSchema;
1344
+ cleanSchema = typeof match$2 === "object" && match$2 !== null && !Array.isArray(match$2) ? Object.fromEntries(Object.entries(match$2).filter((param2) => param2[0] !== "default")) : match$2;
1345
+ properties[match$1] = cleanSchema;
1346
+ let match$3 = param["required"];
1347
+ let isRequired = match$3 === true;
1348
+ let pathRequired = location === "path";
1349
+ if (isRequired || pathRequired) {
1350
+ required.push(match$1);
1351
+ return;
1352
+ }
1353
+ });
1354
+ if (Object.entries(properties).length === 0) {
1355
+ return;
1356
+ }
1357
+ let obj = {};
1358
+ obj["type"] = "object";
1359
+ obj["properties"] = properties;
1360
+ obj["required"] = required;
1361
+ return obj;
1362
+ }
1363
+ function parsePathParameters(pathsJson) {
1364
+ if (typeof pathsJson !== "object" || pathsJson === null || Array.isArray(pathsJson)) {
1365
+ return {
1366
+ TAG: "Ok",
1367
+ _0: []
1368
+ };
1369
+ }
1370
+ let results = Object.entries(pathsJson).flatMap((param) => {
1371
+ let methodsJson = param[1];
1372
+ let path2 = param[0];
1373
+ if (typeof methodsJson === "object" && methodsJson !== null && !Array.isArray(methodsJson)) {
1374
+ return filterMap(Object.entries(methodsJson), (param2) => {
1375
+ let opJson = param2[1];
1376
+ let method = param2[0];
1377
+ let httpMethods = [
1378
+ "get",
1379
+ "post",
1380
+ "put",
1381
+ "patch",
1382
+ "delete"
1383
+ ];
1384
+ if (!httpMethods.includes(method)) {
1385
+ return;
1386
+ }
1387
+ if (typeof opJson !== "object" || opJson === null || Array.isArray(opJson)) {
1388
+ return;
1389
+ }
1390
+ let match = opJson["parameters"];
1391
+ if (match === void 0) {
1392
+ return;
1393
+ }
1394
+ if (!Array.isArray(match)) {
1395
+ return;
1396
+ }
1397
+ let objJson = buildParamsObjectJson(match);
1398
+ if (objJson === void 0) {
1399
+ return;
1400
+ }
1401
+ let name = ucFirst(method) + pathToName(path2) + "Params";
1402
+ let schemaType = parse(objJson);
1403
+ if (schemaType.TAG === "Ok") {
1404
+ return {
1405
+ TAG: "Ok",
1406
+ _0: {
1407
+ name,
1408
+ schema: schemaType._0,
1409
+ discriminatorTag: void 0,
1410
+ discriminatorPropertyName: void 0,
1411
+ fieldDiscriminators: void 0
1412
+ }
1413
+ };
1414
+ } else {
1415
+ return {
1416
+ TAG: "Error",
1417
+ _0: schemaType._0
1418
+ };
1419
+ }
1420
+ });
1421
+ } else {
1422
+ return [];
1423
+ }
1424
+ });
1425
+ let errors = filterMap(results, (r) => {
1426
+ if (r.TAG === "Ok") {
1427
+ return;
1428
+ } else {
1429
+ return r._0;
1430
+ }
1431
+ }).flat();
1432
+ if (errors.length > 0) {
1433
+ return {
1434
+ TAG: "Error",
1435
+ _0: errors
1436
+ };
1437
+ }
1438
+ let schemas = filterMap(results, (r) => {
1439
+ if (r.TAG === "Ok") {
1440
+ return r._0;
1441
+ }
1442
+ });
1443
+ return {
1444
+ TAG: "Ok",
1445
+ _0: schemas
1446
+ };
1447
+ }
1448
+ function extractAllDiscriminatorMappings(json) {
1449
+ let result = {};
1450
+ let walk = (j) => {
1451
+ if (Array.isArray(j)) {
1452
+ j.forEach(walk);
1453
+ return;
1454
+ }
1455
+ switch (typeof j) {
1456
+ case "object":
1457
+ let match = j["oneOf"];
1458
+ let match$1 = j["discriminator"];
1459
+ if (Array.isArray(match) && typeof match$1 === "object" && match$1 !== null && !Array.isArray(match$1)) {
1460
+ let match$2 = match$1["mapping"];
1461
+ if (typeof match$2 === "object" && match$2 !== null && !Array.isArray(match$2)) {
1462
+ Object.entries(match$2).forEach((param) => {
1463
+ let refValue = param[1];
1464
+ if (typeof refValue !== "string") {
1465
+ return;
1466
+ }
1467
+ let parts = refValue.split("/");
1468
+ let schemaName = parts[parts.length - 1 | 0];
1469
+ if (schemaName !== void 0) {
1470
+ result[schemaName] = param[0];
1471
+ return;
1472
+ }
1473
+ });
1474
+ }
1475
+ }
1476
+ Object.entries(j).forEach((param) => walk(param[1]));
1477
+ return;
1478
+ default:
1479
+ return;
1480
+ }
1481
+ };
1482
+ walk(json);
1483
+ return result;
1484
+ }
1485
+ function rewriteVariantTagsInType(schema, tagByRef) {
1486
+ if (typeof schema !== "object") {
1487
+ return schema;
1488
+ }
1489
+ switch (schema._tag) {
1490
+ case "Optional":
1491
+ return {
1492
+ _tag: "Optional",
1493
+ _0: rewriteVariantTagsInType(schema._0, tagByRef)
1494
+ };
1495
+ case "Nullable":
1496
+ return {
1497
+ _tag: "Nullable",
1498
+ _0: rewriteVariantTagsInType(schema._0, tagByRef)
1499
+ };
1500
+ case "Object":
1501
+ return {
1502
+ _tag: "Object",
1503
+ _0: schema._0.map((f) => ({
1504
+ name: f.name,
1505
+ type: rewriteVariantTagsInType(f.type, tagByRef),
1506
+ required: f.required
1507
+ }))
1508
+ };
1509
+ case "Array":
1510
+ return {
1511
+ _tag: "Array",
1512
+ _0: rewriteVariantTagsInType(schema._0, tagByRef)
1513
+ };
1514
+ case "PolyVariant":
1515
+ let newCases = schema._0.map((c2) => {
1516
+ let refName = c2.payload;
1517
+ if (typeof refName !== "object") {
1518
+ return {
1519
+ _tag: c2._tag,
1520
+ payload: rewriteVariantTagsInType(refName, tagByRef)
1521
+ };
1522
+ }
1523
+ if (refName._tag !== "Ref") {
1524
+ return {
1525
+ _tag: c2._tag,
1526
+ payload: rewriteVariantTagsInType(refName, tagByRef)
1527
+ };
1528
+ }
1529
+ let actualTag = tagByRef[refName._0];
1530
+ if (actualTag !== void 0 && actualTag !== c2._tag) {
1531
+ return {
1532
+ _tag: actualTag,
1533
+ payload: c2.payload
1534
+ };
1535
+ } else {
1536
+ return c2;
1537
+ }
1538
+ });
1539
+ return {
1540
+ _tag: "PolyVariant",
1541
+ _0: newCases
1542
+ };
1543
+ case "Dict":
1544
+ return {
1545
+ _tag: "Dict",
1546
+ _0: rewriteVariantTagsInType(schema._0, tagByRef)
1547
+ };
1548
+ case "Union":
1549
+ return {
1550
+ _tag: "Union",
1551
+ _0: schema._0.map((t) => rewriteVariantTagsInType(t, tagByRef))
1552
+ };
1553
+ default:
1554
+ return schema;
1555
+ }
1556
+ }
1557
+ function resolveRefTagsInPolyVariants(schemas, mappingByRef) {
1558
+ let tagByRef = {};
1559
+ schemas.forEach((s) => {
1560
+ let tag = s.discriminatorTag;
1561
+ if (tag !== void 0) {
1562
+ tagByRef[s.name] = tag;
1563
+ return;
1564
+ }
1565
+ });
1566
+ Object.entries(mappingByRef).forEach((param) => {
1567
+ tagByRef[param[0]] = param[1];
1568
+ });
1569
+ return schemas.map((s) => ({
1570
+ name: s.name,
1571
+ schema: rewriteVariantTagsInType(s.schema, tagByRef),
1572
+ discriminatorTag: s.discriminatorTag,
1573
+ discriminatorPropertyName: s.discriminatorPropertyName,
1574
+ fieldDiscriminators: s.fieldDiscriminators
1575
+ }));
1576
+ }
1577
+ function parseDocument(json) {
1578
+ if (typeof json === "object" && json !== null && !Array.isArray(json)) {
1579
+ let componentsJson = json["components"];
1580
+ let componentSchemas = componentsJson !== void 0 ? parseComponentSchemas(componentsJson) : {
1581
+ TAG: "Ok",
1582
+ _0: []
1583
+ };
1584
+ let pathsJson = json["paths"];
1585
+ let pathSchemas = pathsJson !== void 0 ? parsePathResponses(pathsJson) : {
1586
+ TAG: "Ok",
1587
+ _0: []
1588
+ };
1589
+ let pathsJson$1 = json["paths"];
1590
+ let paramSchemas = pathsJson$1 !== void 0 ? parsePathParameters(pathsJson$1) : {
1591
+ TAG: "Ok",
1592
+ _0: []
1593
+ };
1594
+ let mappingByRef = extractAllDiscriminatorMappings(json);
1595
+ let exit = 0;
1596
+ if (componentSchemas.TAG === "Ok" && pathSchemas.TAG === "Ok") {
1597
+ if (paramSchemas.TAG === "Ok") {
1598
+ return {
1599
+ TAG: "Ok",
1600
+ _0: resolveRefTagsInPolyVariants(componentSchemas._0.concat(pathSchemas._0).concat(paramSchemas._0), mappingByRef)
1601
+ };
1602
+ }
1603
+ exit = 2;
1604
+ } else {
1605
+ exit = 2;
1606
+ }
1607
+ if (exit === 2) {
1608
+ let errs = filterMap([
1609
+ componentSchemas,
1610
+ pathSchemas,
1611
+ paramSchemas
1612
+ ], (r) => {
1613
+ if (r.TAG === "Ok") {
1614
+ return;
1615
+ } else {
1616
+ return r._0;
1617
+ }
1618
+ }).flat();
1619
+ return {
1620
+ TAG: "Error",
1621
+ _0: errs
1622
+ };
1623
+ }
1624
+ }
1625
+ return {
1626
+ TAG: "Error",
1627
+ _0: [makeError({
1628
+ TAG: "InvalidJson",
1629
+ _0: "document must be an object"
1630
+ }, void 0, void 0, void 0)]
1631
+ };
1632
+ }
1633
+
1634
+ // src/CodegenHelpers.mjs
1635
+ var reservedKeywords = [
1636
+ "type",
1637
+ "let",
1638
+ "rec",
1639
+ "and",
1640
+ "as",
1641
+ "open",
1642
+ "include",
1643
+ "module",
1644
+ "sig",
1645
+ "struct",
1646
+ "exception",
1647
+ "external",
1648
+ "if",
1649
+ "else",
1650
+ "switch",
1651
+ "while",
1652
+ "for",
1653
+ "try",
1654
+ "catch",
1655
+ "when",
1656
+ "true",
1657
+ "false",
1658
+ "assert",
1659
+ "lazy",
1660
+ "constraint",
1661
+ "functor",
1662
+ "class",
1663
+ "method",
1664
+ "object",
1665
+ "private",
1666
+ "public",
1667
+ "virtual",
1668
+ "mutable",
1669
+ "new",
1670
+ "inherit",
1671
+ "initializer",
1672
+ "val",
1673
+ "with",
1674
+ "match",
1675
+ "of",
1676
+ "fun",
1677
+ "function",
1678
+ "in",
1679
+ "do",
1680
+ "done",
1681
+ "begin",
1682
+ "end",
1683
+ "then",
1684
+ "to",
1685
+ "downto",
1686
+ "or",
1687
+ "land",
1688
+ "lor",
1689
+ "lxor",
1690
+ "lsl",
1691
+ "lsr",
1692
+ "asr",
1693
+ "mod",
1694
+ "await",
1695
+ "async"
1696
+ ];
1697
+ function isReservedKeyword(name) {
1698
+ return reservedKeywords.includes(name);
1699
+ }
1700
+ function lcFirst(s) {
1701
+ if (s.length === 0) {
1702
+ return s;
1703
+ }
1704
+ let first = s.charAt(0).toLowerCase();
1705
+ let rest = s.slice(1);
1706
+ return first + rest;
1707
+ }
1708
+ function ucFirst2(s) {
1709
+ if (s.length === 0) {
1710
+ return s;
1711
+ }
1712
+ let first = s.charAt(0).toUpperCase();
1713
+ let rest = s.slice(1);
1714
+ return first + rest;
1715
+ }
1716
+ function isOptionalType(schema) {
1717
+ if (typeof schema !== "object") {
1718
+ return false;
1719
+ }
1720
+ switch (schema._tag) {
1721
+ case "Optional":
1722
+ case "Nullable":
1723
+ return true;
1724
+ default:
1725
+ return false;
1726
+ }
1727
+ }
1728
+ function isNullableType(schema) {
1729
+ if (typeof schema !== "object") {
1730
+ return false;
1731
+ } else {
1732
+ return schema._tag === "Nullable";
1733
+ }
1734
+ }
1735
+ function getTagForType(t) {
1736
+ if (typeof t !== "object") {
1737
+ switch (t) {
1738
+ case "String":
1739
+ return "String";
1740
+ case "Number":
1741
+ return "Float";
1742
+ case "Integer":
1743
+ return "Int";
1744
+ case "Boolean":
1745
+ return "Bool";
1746
+ case "Null":
1747
+ return "Null";
1748
+ case "Unknown":
1749
+ return "Unknown";
1750
+ }
1751
+ } else {
1752
+ switch (t._tag) {
1753
+ case "Optional":
1754
+ return `Option` + getTagForType(t._0);
1755
+ case "Nullable":
1756
+ return `Null` + getTagForType(t._0);
1757
+ case "Object":
1758
+ return "Object";
1759
+ case "Array":
1760
+ return `Array` + getTagForType(t._0);
1761
+ case "Ref":
1762
+ return ucFirst2(t._0);
1763
+ case "Enum":
1764
+ return "Enum";
1765
+ case "PolyVariant":
1766
+ return "Variant";
1767
+ case "Dict":
1768
+ return "Dict";
1769
+ case "Union":
1770
+ return "Union";
1771
+ }
1772
+ }
1773
+ }
1774
+ function hasUnion(_schema) {
1775
+ while (true) {
1776
+ let schema = _schema;
1777
+ if (typeof schema !== "object") {
1778
+ return false;
1779
+ }
1780
+ switch (schema._tag) {
1781
+ case "Object":
1782
+ return schema._0.some((f) => hasUnion(f.type));
1783
+ case "PolyVariant":
1784
+ return schema._0.some((c2) => hasUnion(c2.payload));
1785
+ case "Optional":
1786
+ case "Nullable":
1787
+ case "Array":
1788
+ case "Dict":
1789
+ _schema = schema._0;
1790
+ continue;
1791
+ case "Union":
1792
+ return true;
1793
+ default:
1794
+ return false;
1795
+ }
1796
+ }
1797
+ ;
1798
+ }
1799
+ function isPrimitiveOnlyUnion(types) {
1800
+ let allPrimitive = types.every((t) => {
1801
+ if (typeof t === "object") {
1802
+ return false;
1803
+ }
1804
+ switch (t) {
1805
+ case "String":
1806
+ case "Number":
1807
+ case "Integer":
1808
+ case "Boolean":
1809
+ return true;
1810
+ default:
1811
+ return false;
1812
+ }
1813
+ });
1814
+ if (!allPrimitive) {
1815
+ return false;
1816
+ }
1817
+ let hasFloat = types.some((t) => t === "Number");
1818
+ let hasInt = types.some((t) => t === "Integer");
1819
+ return !(hasFloat && hasInt);
1820
+ }
1821
+
1822
+ // node_modules/@rescript/runtime/lib/es6/Primitive_bool.js
1823
+ function compare(x, y) {
1824
+ if (x) {
1825
+ if (y) {
1826
+ return 0;
1827
+ } else {
1828
+ return 1;
1829
+ }
1830
+ } else if (y) {
1831
+ return -1;
1832
+ } else {
1833
+ return 0;
1834
+ }
1835
+ }
1836
+
1837
+ // node_modules/@rescript/runtime/lib/es6/Primitive_float.js
1838
+ function compare2(x, y) {
1839
+ if (x === y) {
1840
+ return 0;
1841
+ } else if (x < y) {
1842
+ return -1;
1843
+ } else if (x > y || x === x) {
1844
+ return 1;
1845
+ } else if (y === y) {
1846
+ return -1;
1847
+ } else {
1848
+ return 0;
1849
+ }
1850
+ }
1851
+
1852
+ // node_modules/@rescript/runtime/lib/es6/Primitive_string.js
1853
+ function compare3(s1, s2) {
1854
+ if (s1 === s2) {
1855
+ return 0;
1856
+ } else if (s1 < s2) {
1857
+ return -1;
1858
+ } else {
1859
+ return 1;
1860
+ }
1861
+ }
1862
+
1863
+ // node_modules/@rescript/runtime/lib/es6/Primitive_object.js
1864
+ var for_in = (function(o, foo) {
1865
+ for (var x in o) {
1866
+ foo(x);
1867
+ }
1868
+ });
1869
+ function compare4(a, b) {
1870
+ if (a === b) {
1871
+ return 0;
1872
+ }
1873
+ let a_type = typeof a;
1874
+ let b_type = typeof b;
1875
+ switch (a_type) {
1876
+ case "bigint":
1877
+ if (b_type === "bigint") {
1878
+ return compare2(a, b);
1879
+ }
1880
+ break;
1881
+ case "boolean":
1882
+ if (b_type === "boolean") {
1883
+ return compare(a, b);
1884
+ }
1885
+ break;
1886
+ case "function":
1887
+ if (b_type === "function") {
1888
+ throw {
1889
+ RE_EXN_ID: "Invalid_argument",
1890
+ _1: "compare: functional value",
1891
+ Error: new Error()
1892
+ };
1893
+ }
1894
+ break;
1895
+ case "number":
1896
+ if (b_type === "number") {
1897
+ return compare2(a, b);
1898
+ }
1899
+ break;
1900
+ case "string":
1901
+ if (b_type === "string") {
1902
+ return compare3(a, b);
1903
+ } else {
1904
+ return 1;
1905
+ }
1906
+ case "undefined":
1907
+ return -1;
1908
+ }
1909
+ switch (b_type) {
1910
+ case "string":
1911
+ return -1;
1912
+ case "undefined":
1913
+ return 1;
1914
+ default:
1915
+ if (a_type === "boolean") {
1916
+ return 1;
1917
+ }
1918
+ if (b_type === "boolean") {
1919
+ return -1;
1920
+ }
1921
+ if (a_type === "function") {
1922
+ return 1;
1923
+ }
1924
+ if (b_type === "function") {
1925
+ return -1;
1926
+ }
1927
+ if (a_type === "number") {
1928
+ if (b === null || b.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
1929
+ return 1;
1930
+ } else {
1931
+ return -1;
1932
+ }
1933
+ }
1934
+ if (b_type === "number") {
1935
+ if (a === null || a.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
1936
+ return -1;
1937
+ } else {
1938
+ return 1;
1939
+ }
1940
+ }
1941
+ if (a === null) {
1942
+ if (b.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
1943
+ return 1;
1944
+ } else {
1945
+ return -1;
1946
+ }
1947
+ }
1948
+ if (b === null) {
1949
+ if (a.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
1950
+ return -1;
1951
+ } else {
1952
+ return 1;
1953
+ }
1954
+ }
1955
+ if (a.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
1956
+ if (b.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
1957
+ return aux_obj_compare(a, b);
1958
+ } else {
1959
+ return -1;
1960
+ }
1961
+ }
1962
+ let tag_a = a.TAG;
1963
+ let tag_b = b.TAG;
1964
+ if (tag_a !== tag_b) {
1965
+ if (tag_a < tag_b) {
1966
+ return -1;
1967
+ } else {
1968
+ return 1;
1969
+ }
1970
+ }
1971
+ let len_a = a.length | 0;
1972
+ let len_b = b.length | 0;
1973
+ if (len_a === len_b) {
1974
+ if (Array.isArray(a)) {
1975
+ let _i = 0;
1976
+ while (true) {
1977
+ let i = _i;
1978
+ if (i === len_a) {
1979
+ return 0;
1980
+ }
1981
+ let res = compare4(a[i], b[i]);
1982
+ if (res !== 0) {
1983
+ return res;
1984
+ }
1985
+ _i = i + 1 | 0;
1986
+ continue;
1987
+ }
1988
+ ;
1989
+ } else if (a instanceof Date && b instanceof Date) {
1990
+ return a - b;
1991
+ } else {
1992
+ return aux_obj_compare(a, b);
1993
+ }
1994
+ } else if (len_a < len_b) {
1995
+ let _i$1 = 0;
1996
+ while (true) {
1997
+ let i$1 = _i$1;
1998
+ if (i$1 === len_a) {
1999
+ return -1;
2000
+ }
2001
+ let res$1 = compare4(a[i$1], b[i$1]);
2002
+ if (res$1 !== 0) {
2003
+ return res$1;
2004
+ }
2005
+ _i$1 = i$1 + 1 | 0;
2006
+ continue;
2007
+ }
2008
+ ;
2009
+ } else {
2010
+ let _i$2 = 0;
2011
+ while (true) {
2012
+ let i$2 = _i$2;
2013
+ if (i$2 === len_b) {
2014
+ return 1;
2015
+ }
2016
+ let res$2 = compare4(a[i$2], b[i$2]);
2017
+ if (res$2 !== 0) {
2018
+ return res$2;
2019
+ }
2020
+ _i$2 = i$2 + 1 | 0;
2021
+ continue;
2022
+ }
2023
+ ;
2024
+ }
2025
+ }
2026
+ }
2027
+ function aux_obj_compare(a, b) {
2028
+ let min_key_lhs = {
2029
+ contents: void 0
2030
+ };
2031
+ let min_key_rhs = {
2032
+ contents: void 0
2033
+ };
2034
+ let do_key = (param, key) => {
2035
+ let min_key = param[2];
2036
+ let b2 = param[1];
2037
+ if (!(!Object.prototype.hasOwnProperty.call(b2, key) || compare4(param[0][key], b2[key]) > 0)) {
2038
+ return;
2039
+ }
2040
+ let mk = min_key.contents;
2041
+ if (mk !== void 0 && key >= mk) {
2042
+ return;
2043
+ } else {
2044
+ min_key.contents = key;
2045
+ return;
2046
+ }
2047
+ };
2048
+ let do_key_a = (key) => do_key([
2049
+ a,
2050
+ b,
2051
+ min_key_rhs
2052
+ ], key);
2053
+ let do_key_b = (key) => do_key([
2054
+ b,
2055
+ a,
2056
+ min_key_lhs
2057
+ ], key);
2058
+ for_in(a, do_key_a);
2059
+ for_in(b, do_key_b);
2060
+ let match = min_key_lhs.contents;
2061
+ let match$1 = min_key_rhs.contents;
2062
+ if (match !== void 0) {
2063
+ if (match$1 !== void 0) {
2064
+ return compare3(match, match$1);
2065
+ } else {
2066
+ return -1;
2067
+ }
2068
+ } else if (match$1 !== void 0) {
2069
+ return 1;
2070
+ } else {
2071
+ return 0;
2072
+ }
2073
+ }
2074
+ function greaterthan(a, b) {
2075
+ if ((typeof a === "number" || typeof a === "bigint") && (typeof b === "number" || typeof b === "bigint")) {
2076
+ return a > b;
2077
+ } else {
2078
+ return compare4(a, b) > 0;
2079
+ }
2080
+ }
2081
+ function lessthan(a, b) {
2082
+ if ((typeof a === "number" || typeof a === "bigint") && (typeof b === "number" || typeof b === "bigint")) {
2083
+ return a < b;
2084
+ } else {
2085
+ return compare4(a, b) < 0;
2086
+ }
2087
+ }
2088
+
2089
+ // src/CodegenTransforms.mjs
2090
+ function collectEnumsFromType(parentType, fieldPath, _schema) {
2091
+ while (true) {
2092
+ let schema = _schema;
2093
+ if (typeof schema !== "object") {
2094
+ return [];
2095
+ }
2096
+ switch (schema._tag) {
2097
+ case "Object":
2098
+ return schema._0.flatMap((f) => collectEnumsFromType(parentType, fieldPath.concat([f.name]), f.type));
2099
+ case "Enum":
2100
+ if (fieldPath.length > 0) {
2101
+ return [{
2102
+ parentType,
2103
+ fieldPath,
2104
+ values: schema._0
2105
+ }];
2106
+ } else {
2107
+ return [];
2108
+ }
2109
+ case "PolyVariant":
2110
+ return schema._0.flatMap((c2) => collectEnumsFromType(parentType, fieldPath, c2.payload));
2111
+ case "Optional":
2112
+ case "Nullable":
2113
+ case "Array":
2114
+ case "Dict":
2115
+ break;
2116
+ case "Union":
2117
+ return schema._0.flatMap((t) => collectEnumsFromType(parentType, fieldPath, t));
2118
+ default:
2119
+ return [];
2120
+ }
2121
+ _schema = schema._0;
2122
+ continue;
2123
+ }
2124
+ ;
2125
+ }
2126
+ function collectInlineEnums(schemas) {
2127
+ return schemas.flatMap((s) => {
2128
+ let match = s.schema;
2129
+ if (typeof match !== "object") {
2130
+ return collectEnumsFromType(s.name, [], s.schema);
2131
+ } else if (match._tag === "Enum") {
2132
+ return [];
2133
+ } else {
2134
+ return collectEnumsFromType(s.name, [], s.schema);
2135
+ }
2136
+ });
2137
+ }
2138
+ function camelize(s) {
2139
+ let parts = s.replace(/-/g, "_").split("_").filter((p) => p !== "");
2140
+ let first = parts[0];
2141
+ if (first === void 0) {
2142
+ return s;
2143
+ }
2144
+ let rest = parts.slice(1);
2145
+ return lcFirst(first) + rest.map(ucFirst2).join("");
2146
+ }
2147
+ function occurrenceKey(occ) {
2148
+ return occ.parentType + "::" + occ.fieldPath.join("/");
2149
+ }
2150
+ function valuesCanonicalKey(values) {
2151
+ let cmp = (a, b) => {
2152
+ if (lessthan(a, b)) {
2153
+ return -1;
2154
+ } else if (greaterthan(a, b)) {
2155
+ return 1;
2156
+ } else {
2157
+ return 0;
2158
+ }
2159
+ };
2160
+ return values.toSorted(cmp).join("");
2161
+ }
2162
+ function leafFieldName(occ) {
2163
+ let s = occ.fieldPath[occ.fieldPath.length - 1 | 0];
2164
+ if (s !== void 0) {
2165
+ return s;
2166
+ } else {
2167
+ return "unknown";
2168
+ }
2169
+ }
2170
+ function replaceEnumsInType(parentType, fieldPath, names, schema) {
2171
+ if (typeof schema !== "object") {
2172
+ return schema;
2173
+ }
2174
+ switch (schema._tag) {
2175
+ case "Optional":
2176
+ return {
2177
+ _tag: "Optional",
2178
+ _0: replaceEnumsInType(parentType, fieldPath, names, schema._0)
2179
+ };
2180
+ case "Nullable":
2181
+ return {
2182
+ _tag: "Nullable",
2183
+ _0: replaceEnumsInType(parentType, fieldPath, names, schema._0)
2184
+ };
2185
+ case "Object":
2186
+ return {
2187
+ _tag: "Object",
2188
+ _0: schema._0.map((f) => {
2189
+ let newType = replaceEnumsInType(parentType, fieldPath.concat([f.name]), names, f.type);
2190
+ return {
2191
+ name: f.name,
2192
+ type: newType,
2193
+ required: f.required
2194
+ };
2195
+ })
2196
+ };
2197
+ case "Array":
2198
+ return {
2199
+ _tag: "Array",
2200
+ _0: replaceEnumsInType(parentType, fieldPath, names, schema._0)
2201
+ };
2202
+ case "Enum":
2203
+ if (fieldPath.length <= 0) {
2204
+ return schema;
2205
+ }
2206
+ let key = parentType + "::" + fieldPath.join("/");
2207
+ let name = names[key];
2208
+ if (name !== void 0) {
2209
+ return {
2210
+ _tag: "Ref",
2211
+ _0: ucFirst2(name)
2212
+ };
2213
+ } else {
2214
+ return schema;
2215
+ }
2216
+ case "PolyVariant":
2217
+ return {
2218
+ _tag: "PolyVariant",
2219
+ _0: schema._0.map((c2) => {
2220
+ let payload = replaceEnumsInType(parentType, fieldPath, names, c2.payload);
2221
+ return {
2222
+ _tag: c2._tag,
2223
+ payload
2224
+ };
2225
+ })
2226
+ };
2227
+ case "Dict":
2228
+ return {
2229
+ _tag: "Dict",
2230
+ _0: replaceEnumsInType(parentType, fieldPath, names, schema._0)
2231
+ };
2232
+ case "Union":
2233
+ return {
2234
+ _tag: "Union",
2235
+ _0: schema._0.map((t) => replaceEnumsInType(parentType, fieldPath, names, t))
2236
+ };
2237
+ default:
2238
+ return schema;
2239
+ }
2240
+ }
2241
+ function replaceInlineEnums(schemas, names) {
2242
+ return schemas.map((s) => {
2243
+ let match = s.schema;
2244
+ let newSchema;
2245
+ let exit = 0;
2246
+ if (typeof match !== "object" || match._tag !== "Enum") {
2247
+ exit = 1;
2248
+ } else {
2249
+ newSchema = s.schema;
2250
+ }
2251
+ if (exit === 1) {
2252
+ newSchema = replaceEnumsInType(s.name, [], names, s.schema);
2253
+ }
2254
+ return {
2255
+ name: s.name,
2256
+ schema: newSchema,
2257
+ discriminatorTag: s.discriminatorTag,
2258
+ discriminatorPropertyName: s.discriminatorPropertyName,
2259
+ fieldDiscriminators: s.fieldDiscriminators
2260
+ };
2261
+ });
2262
+ }
2263
+ function buildExtractedEnumSchemas(occurrences, names) {
2264
+ let seen = {};
2265
+ let result = [];
2266
+ occurrences.forEach((occ) => {
2267
+ let key = occurrenceKey(occ);
2268
+ let name = names[key];
2269
+ if (name === void 0) {
2270
+ return;
2271
+ }
2272
+ let typeName = ucFirst2(name);
2273
+ if (isNone(seen[typeName])) {
2274
+ seen[typeName] = true;
2275
+ result.push({
2276
+ name: typeName,
2277
+ schema: {
2278
+ _tag: "Enum",
2279
+ _0: occ.values
2280
+ },
2281
+ discriminatorTag: void 0,
2282
+ discriminatorPropertyName: void 0,
2283
+ fieldDiscriminators: void 0
2284
+ });
2285
+ return;
2286
+ }
2287
+ });
2288
+ return result;
2289
+ }
2290
+ function resolveEnumNames(occurrences, topLevelNames) {
2291
+ let topLevelSet = {};
2292
+ topLevelNames.forEach((n) => {
2293
+ topLevelSet[lcFirst(n)] = true;
2294
+ });
2295
+ let buckets = {};
2296
+ occurrences.forEach((occ) => {
2297
+ let leaf = leafFieldName(occ);
2298
+ let vKey = valuesCanonicalKey(occ.values);
2299
+ let set = buckets[leaf];
2300
+ if (set !== void 0) {
2301
+ set[vKey] = true;
2302
+ return;
2303
+ }
2304
+ let set$1 = {};
2305
+ set$1[vKey] = true;
2306
+ buckets[leaf] = set$1;
2307
+ });
2308
+ let result = {};
2309
+ occurrences.forEach((occ) => {
2310
+ let leaf = leafFieldName(occ);
2311
+ let camelized = camelize(leaf);
2312
+ let distinctSets = mapOr(buckets[leaf], 1, (set) => Object.keys(set).length);
2313
+ let collidesTopLevel = isSome(topLevelSet[camelized]);
2314
+ let baseName = distinctSets > 1 || collidesTopLevel ? lcFirst(occ.parentType) + ucFirst2(camelized) : camelized;
2315
+ let name = isReservedKeyword(baseName) ? baseName + "_" : baseName;
2316
+ result[occurrenceKey(occ)] = name;
2317
+ });
2318
+ return result;
2319
+ }
2320
+ function isRefPlusDictUnion(types) {
2321
+ if (types.length !== 2) {
2322
+ return;
2323
+ }
2324
+ let hasDict = types.some((t) => {
2325
+ if (typeof t !== "object") {
2326
+ return false;
2327
+ }
2328
+ if (t._tag !== "Dict") {
2329
+ return false;
2330
+ }
2331
+ let tmp = t._0;
2332
+ if (typeof tmp !== "object") {
2333
+ return tmp === "String";
2334
+ } else {
2335
+ return false;
2336
+ }
2337
+ });
2338
+ let refName = findMap(types, (t) => {
2339
+ if (typeof t !== "object" || t._tag !== "Ref") {
2340
+ return;
2341
+ } else {
2342
+ return t._0;
2343
+ }
2344
+ });
2345
+ if (hasDict) {
2346
+ return refName;
2347
+ }
2348
+ }
2349
+ function isPrimitivePlusDictUnion(types) {
2350
+ if (types.length !== 2) {
2351
+ return;
2352
+ }
2353
+ let hasDict = types.some((t) => {
2354
+ if (typeof t !== "object") {
2355
+ return false;
2356
+ }
2357
+ if (t._tag !== "Dict") {
2358
+ return false;
2359
+ }
2360
+ let tmp = t._0;
2361
+ if (typeof tmp !== "object") {
2362
+ return tmp === "String";
2363
+ } else {
2364
+ return false;
2365
+ }
2366
+ });
2367
+ let primitiveName = findMap(types, (t) => {
2368
+ if (typeof t === "object") {
2369
+ return;
2370
+ }
2371
+ switch (t) {
2372
+ case "String":
2373
+ return "string";
2374
+ case "Number":
2375
+ return "float";
2376
+ case "Integer":
2377
+ return "int";
2378
+ case "Boolean":
2379
+ return "bool";
2380
+ default:
2381
+ return;
2382
+ }
2383
+ });
2384
+ if (hasDict) {
2385
+ return primitiveName;
2386
+ }
2387
+ }
2388
+ function getUnionName(types) {
2389
+ let names = types.map((t) => {
2390
+ if (typeof t !== "object") {
2391
+ switch (t) {
2392
+ case "String":
2393
+ return "string";
2394
+ case "Number":
2395
+ return "float";
2396
+ case "Integer":
2397
+ return "int";
2398
+ case "Boolean":
2399
+ return "bool";
2400
+ case "Null":
2401
+ return "null";
2402
+ default:
2403
+ return "unknown";
2404
+ }
2405
+ } else {
2406
+ switch (t._tag) {
2407
+ case "Array":
2408
+ return "array";
2409
+ case "Ref":
2410
+ return lcFirst(t._0);
2411
+ case "Dict":
2412
+ return "dict";
2413
+ default:
2414
+ return "unknown";
2415
+ }
2416
+ }
2417
+ });
2418
+ if (names.length === 0) {
2419
+ return "emptyUnion";
2420
+ }
2421
+ let first = getOr(names[0], "unknown");
2422
+ let rest = names.slice(1);
2423
+ return first + rest.map((n) => "Or" + ucFirst2(n)).join("");
2424
+ }
2425
+ function getPolyVariantName(cases) {
2426
+ return getUnionName(cases.map((c2) => c2.payload));
2427
+ }
2428
+ function extractUnionsFromType(_schema) {
2429
+ while (true) {
2430
+ let schema = _schema;
2431
+ if (typeof schema !== "object") {
2432
+ return [];
2433
+ }
2434
+ switch (schema._tag) {
2435
+ case "Object":
2436
+ return schema._0.flatMap((field) => extractUnionsFromType(field.type));
2437
+ case "PolyVariant":
2438
+ let name = getPolyVariantName(schema._0);
2439
+ return [{
2440
+ name,
2441
+ schema
2442
+ }];
2443
+ case "Optional":
2444
+ case "Nullable":
2445
+ case "Array":
2446
+ case "Dict":
2447
+ _schema = schema._0;
2448
+ continue;
2449
+ case "Union":
2450
+ let types = schema._0;
2451
+ let match = isRefPlusDictUnion(types);
2452
+ if (match !== void 0) {
2453
+ return [];
2454
+ }
2455
+ let name$1 = getUnionName(types);
2456
+ return [{
2457
+ name: name$1,
2458
+ schema
2459
+ }];
2460
+ default:
2461
+ return [];
2462
+ }
2463
+ }
2464
+ ;
2465
+ }
2466
+ function extractUnions(_parentName, schema) {
2467
+ if (typeof schema !== "object") {
2468
+ return [];
2469
+ } else if (schema._tag === "Object") {
2470
+ return schema._0.flatMap((field) => extractUnionsFromType(field.type));
2471
+ } else {
2472
+ return [];
2473
+ }
2474
+ }
2475
+ function replaceUnionInType(schema) {
2476
+ if (typeof schema !== "object") {
2477
+ return schema;
2478
+ }
2479
+ switch (schema._tag) {
2480
+ case "Optional":
2481
+ return {
2482
+ _tag: "Optional",
2483
+ _0: replaceUnionInType(schema._0)
2484
+ };
2485
+ case "Nullable":
2486
+ return {
2487
+ _tag: "Nullable",
2488
+ _0: replaceUnionInType(schema._0)
2489
+ };
2490
+ case "Object":
2491
+ let newFields = schema._0.map((field) => {
2492
+ let newType = replaceUnionInType(field.type);
2493
+ return {
2494
+ name: field.name,
2495
+ type: newType,
2496
+ required: field.required
2497
+ };
2498
+ });
2499
+ return {
2500
+ _tag: "Object",
2501
+ _0: newFields
2502
+ };
2503
+ case "Array":
2504
+ return {
2505
+ _tag: "Array",
2506
+ _0: replaceUnionInType(schema._0)
2507
+ };
2508
+ case "PolyVariant":
2509
+ return {
2510
+ _tag: "Ref",
2511
+ _0: getPolyVariantName(schema._0)
2512
+ };
2513
+ case "Dict":
2514
+ return {
2515
+ _tag: "Dict",
2516
+ _0: replaceUnionInType(schema._0)
2517
+ };
2518
+ case "Union":
2519
+ let types = schema._0;
2520
+ let refName = isRefPlusDictUnion(types);
2521
+ if (refName !== void 0) {
2522
+ return {
2523
+ _tag: "Ref",
2524
+ _0: refName
2525
+ };
2526
+ } else {
2527
+ return {
2528
+ _tag: "Ref",
2529
+ _0: getUnionName(types)
2530
+ };
2531
+ }
2532
+ default:
2533
+ return schema;
2534
+ }
2535
+ }
2536
+ function replaceUnions(_parentName, schema) {
2537
+ if (typeof schema !== "object") {
2538
+ return schema;
2539
+ }
2540
+ if (schema._tag !== "Object") {
2541
+ return schema;
2542
+ }
2543
+ let newFields = schema._0.map((field) => {
2544
+ let newType = replaceUnionInType(field.type);
2545
+ return {
2546
+ name: field.name,
2547
+ type: newType,
2548
+ required: field.required
2549
+ };
2550
+ });
2551
+ return {
2552
+ _tag: "Object",
2553
+ _0: newFields
2554
+ };
2555
+ }
2556
+ function getDependencies(_schema) {
2557
+ while (true) {
2558
+ let schema = _schema;
2559
+ if (typeof schema !== "object") {
2560
+ return [];
2561
+ }
2562
+ switch (schema._tag) {
2563
+ case "Object":
2564
+ return schema._0.flatMap((f) => getDependencies(f.type));
2565
+ case "Ref":
2566
+ return [schema._0];
2567
+ case "Enum":
2568
+ return [];
2569
+ case "PolyVariant":
2570
+ return schema._0.flatMap((c2) => getDependencies(c2.payload));
2571
+ case "Optional":
2572
+ case "Nullable":
2573
+ case "Array":
2574
+ case "Dict":
2575
+ _schema = schema._0;
2576
+ continue;
2577
+ case "Union":
2578
+ return schema._0.flatMap(getDependencies);
2579
+ }
2580
+ }
2581
+ ;
2582
+ }
2583
+ function topologicalSort(schemas) {
2584
+ let schemaMap = {};
2585
+ schemas.forEach((s) => {
2586
+ schemaMap[s.name] = s;
2587
+ });
2588
+ let deps = {};
2589
+ schemas.forEach((s) => {
2590
+ let refNames = getDependencies(s.schema);
2591
+ let validRefs = refNames.filter((name) => isSome(schemaMap[name]));
2592
+ deps[s.name] = validRefs;
2593
+ });
2594
+ let outDegree = {};
2595
+ schemas.forEach((s) => {
2596
+ let myDeps = getOr(deps[s.name], []);
2597
+ outDegree[s.name] = myDeps.length;
2598
+ });
2599
+ let reverseDeps = {};
2600
+ schemas.forEach((s) => {
2601
+ reverseDeps[s.name] = [];
2602
+ });
2603
+ Object.entries(deps).forEach((param) => {
2604
+ let name = param[0];
2605
+ param[1].forEach((refName) => {
2606
+ let arr = reverseDeps[refName];
2607
+ if (arr !== void 0) {
2608
+ arr.push(name);
2609
+ return;
2610
+ }
2611
+ });
2612
+ });
2613
+ let queue = schemas.filter((s) => getOr(outDegree[s.name], 0) === 0).map((s) => s.name);
2614
+ let result = [];
2615
+ let visited = {};
2616
+ let process2 = () => {
2617
+ while (true) {
2618
+ let name = queue.shift();
2619
+ if (name === void 0) {
2620
+ return;
2621
+ }
2622
+ if (isNone(visited[name])) {
2623
+ visited[name] = true;
2624
+ let schema = schemaMap[name];
2625
+ if (schema !== void 0) {
2626
+ result.push(schema);
2627
+ }
2628
+ let dependents = reverseDeps[name];
2629
+ if (dependents !== void 0) {
2630
+ dependents.forEach((depName) => {
2631
+ let current = getOr(outDegree[depName], 0);
2632
+ outDegree[depName] = current - 1 | 0;
2633
+ if ((current - 1 | 0) === 0) {
2634
+ queue.push(depName);
2635
+ return;
2636
+ }
2637
+ });
2638
+ }
2639
+ }
2640
+ continue;
2641
+ }
2642
+ ;
2643
+ };
2644
+ process2();
2645
+ schemas.forEach((s) => {
2646
+ if (isNone(visited[s.name])) {
2647
+ result.push(s);
2648
+ return;
2649
+ }
2650
+ });
2651
+ return result;
2652
+ }
2653
+ function buildSkipSchemaSet(schemas) {
2654
+ let skipSet = {};
2655
+ schemas.forEach((s) => {
2656
+ let types = s.schema;
2657
+ let hasInlineProblem;
2658
+ if (typeof types !== "object") {
2659
+ hasInlineProblem = hasUnion(s.schema);
2660
+ } else {
2661
+ switch (types._tag) {
2662
+ case "PolyVariant":
2663
+ hasInlineProblem = types._0.some((c2) => hasUnion(c2.payload));
2664
+ break;
2665
+ case "Union":
2666
+ hasInlineProblem = types._0.some(hasUnion);
2667
+ break;
2668
+ default:
2669
+ hasInlineProblem = hasUnion(s.schema);
2670
+ }
2671
+ }
2672
+ if (hasInlineProblem) {
2673
+ skipSet[s.name] = true;
2674
+ return;
2675
+ }
2676
+ });
2677
+ let changed = {
2678
+ contents: true
2679
+ };
2680
+ while (changed.contents) {
2681
+ changed.contents = false;
2682
+ schemas.forEach((s) => {
2683
+ if (!isNone(skipSet[s.name])) {
2684
+ return;
2685
+ }
2686
+ let refs = getDependencies(s.schema);
2687
+ let refsSkipSchema = refs.some((refName) => isSome(skipSet[refName]));
2688
+ if (refsSkipSchema) {
2689
+ skipSet[s.name] = true;
2690
+ changed.contents = true;
2691
+ return;
2692
+ }
2693
+ });
2694
+ }
2695
+ ;
2696
+ return skipSet;
2697
+ }
2698
+ function collectUnionWarnings(schemas) {
2699
+ let seen = {};
2700
+ let warnings = [];
2701
+ let findUnions = (_schema) => {
2702
+ while (true) {
2703
+ let schema = _schema;
2704
+ if (typeof schema !== "object") {
2705
+ return [];
2706
+ }
2707
+ switch (schema._tag) {
2708
+ case "Object":
2709
+ return schema._0.flatMap((f) => findUnions(f.type));
2710
+ case "Optional":
2711
+ case "Nullable":
2712
+ case "Array":
2713
+ case "Dict":
2714
+ _schema = schema._0;
2715
+ continue;
2716
+ case "Union":
2717
+ return [schema._0];
2718
+ default:
2719
+ return [];
2720
+ }
2721
+ }
2722
+ ;
2723
+ };
2724
+ schemas.forEach((s) => {
2725
+ let unions = findUnions(s.schema);
2726
+ unions.forEach((types) => {
2727
+ let unionName = getUnionName(types);
2728
+ if (!isNone(seen[unionName])) {
2729
+ return;
2730
+ }
2731
+ seen[unionName] = true;
2732
+ let refName = isRefPlusDictUnion(types);
2733
+ if (refName !== void 0) {
2734
+ warnings.push(`\u26A0 ` + unionName + `: anyOf without discriminator, simplified to ` + lcFirst(refName));
2735
+ return;
2736
+ }
2737
+ let primName = isPrimitivePlusDictUnion(types);
2738
+ if (primName !== void 0) {
2739
+ warnings.push(`\u26A0 ` + unionName + `: anyOf [` + primName + `, Dict] without discriminator, @tag("_tag") may not work at runtime`);
2740
+ return;
2741
+ }
2742
+ });
2743
+ });
2744
+ return warnings;
2745
+ }
2746
+ function validateUnionDiscriminators(schemas) {
2747
+ let seen = {};
2748
+ let errors = [];
2749
+ let schemasDict = {};
2750
+ schemas.forEach((s) => {
2751
+ schemasDict[s.name] = s.schema;
2752
+ });
2753
+ let tagsDict = {};
2754
+ schemas.forEach((s) => {
2755
+ let tag = s.discriminatorTag;
2756
+ if (tag !== void 0) {
2757
+ tagsDict[s.name] = tag;
2758
+ return;
2759
+ }
2760
+ });
2761
+ let fieldDiscsDict = {};
2762
+ schemas.forEach((s) => {
2763
+ let dict = s.fieldDiscriminators;
2764
+ if (dict !== void 0) {
2765
+ Object.entries(dict).forEach((param) => {
2766
+ fieldDiscsDict[param[0]] = param[1];
2767
+ });
2768
+ return;
2769
+ }
2770
+ });
2771
+ let findUnions = (_schema) => {
2772
+ while (true) {
2773
+ let schema = _schema;
2774
+ if (typeof schema !== "object") {
2775
+ return [];
2776
+ }
2777
+ switch (schema._tag) {
2778
+ case "Object":
2779
+ return schema._0.flatMap((f) => findUnions(f.type));
2780
+ case "Optional":
2781
+ case "Nullable":
2782
+ case "Array":
2783
+ case "Dict":
2784
+ _schema = schema._0;
2785
+ continue;
2786
+ case "Union":
2787
+ return [schema._0];
2788
+ default:
2789
+ return [];
2790
+ }
2791
+ }
2792
+ ;
2793
+ };
2794
+ schemas.forEach((s) => {
2795
+ let unions = findUnions(s.schema);
2796
+ unions.forEach((types) => {
2797
+ let unionName = getUnionName(types);
2798
+ if (!isNone(seen[unionName])) {
2799
+ return;
2800
+ }
2801
+ seen[unionName] = true;
2802
+ if (isPrimitiveOnlyUnion(types)) {
2803
+ return;
2804
+ }
2805
+ let match = isRefPlusDictUnion(types);
2806
+ if (match !== void 0) {
2807
+ return;
2808
+ }
2809
+ let match$1 = isPrimitivePlusDictUnion(types);
2810
+ if (match$1 !== void 0) {
2811
+ return;
2812
+ }
2813
+ if (!isNone(fieldDiscsDict[unionName])) {
2814
+ return;
2815
+ }
2816
+ let allRefsHaveTags = types.every((t) => {
2817
+ if (typeof t !== "object" || t._tag !== "Ref") {
2818
+ return true;
2819
+ } else {
2820
+ return isSome(tagsDict[t._0]);
2821
+ }
2822
+ });
2823
+ if (!allRefsHaveTags) {
2824
+ errors.push(makeError({
2825
+ TAG: "MissingDiscriminator",
2826
+ _0: unionName
2827
+ }, void 0, 'Add discriminator: { propertyName: "type" } to the anyOf/oneOf schema, or use the _tag convention with const values', void 0));
2828
+ return;
2829
+ }
2830
+ });
2831
+ });
2832
+ return errors;
2833
+ }
2834
+
2835
+ // src/IRGen.mjs
2836
+ function convertType(schema) {
2837
+ if (typeof schema !== "object") {
2838
+ switch (schema) {
2839
+ case "String":
2840
+ return {
2841
+ TAG: "Primitive",
2842
+ _0: "PString"
2843
+ };
2844
+ case "Number":
2845
+ return {
2846
+ TAG: "Primitive",
2847
+ _0: "PFloat"
2848
+ };
2849
+ case "Integer":
2850
+ return {
2851
+ TAG: "Primitive",
2852
+ _0: "PInt"
2853
+ };
2854
+ case "Boolean":
2855
+ return {
2856
+ TAG: "Primitive",
2857
+ _0: "PBool"
2858
+ };
2859
+ case "Null":
2860
+ return {
2861
+ TAG: "Primitive",
2862
+ _0: "PUnit"
2863
+ };
2864
+ case "Unknown":
2865
+ return "JSON";
2866
+ }
2867
+ } else {
2868
+ switch (schema._tag) {
2869
+ case "Optional":
2870
+ return {
2871
+ TAG: "Option",
2872
+ _0: convertType(schema._0)
2873
+ };
2874
+ case "Nullable":
2875
+ return {
2876
+ TAG: "Nullable",
2877
+ _0: convertType(schema._0)
2878
+ };
2879
+ case "Object":
2880
+ let fields = schema._0;
2881
+ if (fields.length === 0) {
2882
+ return "JSON";
2883
+ } else {
2884
+ return {
2885
+ TAG: "InlineRecord",
2886
+ _0: fields.map(convertField)
2887
+ };
2888
+ }
2889
+ case "Array":
2890
+ return {
2891
+ TAG: "Array",
2892
+ _0: convertType(schema._0)
2893
+ };
2894
+ case "Ref":
2895
+ return {
2896
+ TAG: "Named",
2897
+ _0: lcFirst(schema._0)
2898
+ };
2899
+ case "Enum":
2900
+ return {
2901
+ TAG: "Enum",
2902
+ _0: schema._0
2903
+ };
2904
+ case "PolyVariant":
2905
+ return {
2906
+ TAG: "InlineVariant",
2907
+ _0: schema._0.map((c2) => {
2908
+ let payload = convertType(c2.payload);
2909
+ return {
2910
+ tag: c2._tag,
2911
+ payload
2912
+ };
2913
+ })
2914
+ };
2915
+ case "Dict":
2916
+ return {
2917
+ TAG: "Dict",
2918
+ _0: convertType(schema._0)
2919
+ };
2920
+ case "Union":
2921
+ return {
2922
+ TAG: "InlineVariant",
2923
+ _0: schema._0.map((t) => {
2924
+ let tag = getTagForType(t);
2925
+ let payload = convertType(t);
2926
+ return {
2927
+ tag,
2928
+ payload
2929
+ };
2930
+ })
2931
+ };
2932
+ }
2933
+ }
2934
+ }
2935
+ function convertField(field) {
2936
+ let baseType = convertType(field.type);
2937
+ let wrappedType = field.required || isOptionalType(field.type) ? baseType : {
2938
+ TAG: "Option",
2939
+ _0: baseType
2940
+ };
2941
+ let annotations = [];
2942
+ if (isNullableType(field.type)) {
2943
+ annotations.push("SNull");
2944
+ }
2945
+ if (isReservedKeyword(field.name)) {
2946
+ annotations.push({
2947
+ TAG: "As",
2948
+ _0: field.name
2949
+ });
2950
+ }
2951
+ let fieldName = isReservedKeyword(field.name) ? field.name + "_" : field.name;
2952
+ return {
2953
+ name: fieldName,
2954
+ annotations,
2955
+ type_: wrappedType
2956
+ };
2957
+ }
2958
+ function convertToIrTypeDef(namedSchema, schemasDict, tagsDict, skipSchemaSet) {
2959
+ let typeName = lcFirst(namedSchema.name);
2960
+ let tagName = getOr(namedSchema.discriminatorPropertyName, "_tag");
2961
+ let shouldSkipSchema = isSome(skipSchemaSet[namedSchema.name]);
2962
+ let cases = namedSchema.schema;
2963
+ if (typeof cases === "object") {
2964
+ switch (cases._tag) {
2965
+ case "PolyVariant":
2966
+ let irCases = cases._0.map((c2) => {
2967
+ let refName = c2.payload;
2968
+ let payload;
2969
+ if (typeof refName !== "object" || refName._tag !== "Ref") {
2970
+ payload = convertType(refName);
2971
+ } else {
2972
+ let refName$1 = refName._0;
2973
+ let other = schemasDict[refName$1];
2974
+ if (other !== void 0) {
2975
+ if (typeof other !== "object" || other._tag !== "Object") {
2976
+ payload = convertType(other);
2977
+ } else {
2978
+ let filtered = other._0.filter((f) => f.name !== tagName);
2979
+ payload = {
2980
+ TAG: "InlineRecord",
2981
+ _0: filtered.map(convertField)
2982
+ };
2983
+ }
2984
+ } else {
2985
+ payload = {
2986
+ TAG: "Named",
2987
+ _0: lcFirst(refName$1)
2988
+ };
2989
+ }
2990
+ }
2991
+ return {
2992
+ tag: ucFirst2(c2._tag),
2993
+ payload
2994
+ };
2995
+ });
2996
+ let baseAnnotations = [
2997
+ "GenType",
2998
+ {
2999
+ TAG: "Tag",
3000
+ _0: tagName
3001
+ }
3002
+ ];
3003
+ let annotations = shouldSkipSchema ? baseAnnotations : baseAnnotations.concat(["Schema"]);
3004
+ return {
3005
+ name: typeName,
3006
+ annotations,
3007
+ kind: {
3008
+ TAG: "VariantDef",
3009
+ _0: irCases
3010
+ }
3011
+ };
3012
+ case "Union":
3013
+ let types = cases._0;
3014
+ if (isPrimitiveOnlyUnion(types)) {
3015
+ let irCases$1 = types.map((t) => {
3016
+ let tag = getTagForType(t);
3017
+ let payload = convertType(t);
3018
+ return {
3019
+ tag,
3020
+ payload
3021
+ };
3022
+ });
3023
+ let baseAnnotations$1 = [
3024
+ "GenType",
3025
+ {
3026
+ TAG: "Tag",
3027
+ _0: tagName
3028
+ },
3029
+ "Unboxed"
3030
+ ];
3031
+ let annotations$1 = shouldSkipSchema ? baseAnnotations$1 : baseAnnotations$1.concat(["Schema"]);
3032
+ return {
3033
+ name: typeName,
3034
+ annotations: annotations$1,
3035
+ kind: {
3036
+ TAG: "VariantDef",
3037
+ _0: irCases$1
3038
+ }
3039
+ };
3040
+ }
3041
+ let irCases$2 = types.map((t) => {
3042
+ if (typeof t === "object" && t._tag === "Ref") {
3043
+ let name = t._0;
3044
+ let tagValue = tagsDict[name];
3045
+ let tag = tagValue !== void 0 ? ucFirst2(tagValue) : ucFirst2(name);
3046
+ let other = schemasDict[name];
3047
+ let payload;
3048
+ if (other !== void 0) {
3049
+ if (typeof other !== "object" || other._tag !== "Object") {
3050
+ payload = convertType(other);
3051
+ } else {
3052
+ let filtered = other._0.filter((f) => f.name !== tagName);
3053
+ payload = {
3054
+ TAG: "InlineRecord",
3055
+ _0: filtered.map(convertField)
3056
+ };
3057
+ }
3058
+ } else {
3059
+ payload = {
3060
+ TAG: "Named",
3061
+ _0: lcFirst(name)
3062
+ };
3063
+ }
3064
+ return {
3065
+ tag,
3066
+ payload
3067
+ };
3068
+ }
3069
+ let tag$1 = getTagForType(t);
3070
+ let payload$1 = convertType(t);
3071
+ return {
3072
+ tag: tag$1,
3073
+ payload: payload$1
3074
+ };
3075
+ });
3076
+ let baseAnnotations$2 = [
3077
+ "GenType",
3078
+ {
3079
+ TAG: "Tag",
3080
+ _0: tagName
3081
+ }
3082
+ ];
3083
+ let annotations$2 = shouldSkipSchema ? baseAnnotations$2 : baseAnnotations$2.concat(["Schema"]);
3084
+ return {
3085
+ name: typeName,
3086
+ annotations: annotations$2,
3087
+ kind: {
3088
+ TAG: "VariantDef",
3089
+ _0: irCases$2
3090
+ }
3091
+ };
3092
+ }
3093
+ }
3094
+ let fields = namedSchema.schema;
3095
+ let kind;
3096
+ if (typeof fields !== "object" || fields._tag !== "Object") {
3097
+ kind = {
3098
+ TAG: "AliasDef",
3099
+ _0: convertType(namedSchema.schema)
3100
+ };
3101
+ } else {
3102
+ let fields$1 = fields._0;
3103
+ kind = fields$1.length > 0 ? {
3104
+ TAG: "RecordDef",
3105
+ _0: fields$1.map(convertField)
3106
+ } : {
3107
+ TAG: "AliasDef",
3108
+ _0: convertType(namedSchema.schema)
3109
+ };
3110
+ }
3111
+ let annotations$3 = shouldSkipSchema ? ["GenType"] : [
3112
+ "GenType",
3113
+ "Schema"
3114
+ ];
3115
+ return {
3116
+ name: typeName,
3117
+ annotations: annotations$3,
3118
+ kind
3119
+ };
3120
+ }
3121
+ function generate(schemas) {
3122
+ let validationErrors = validateUnionDiscriminators(schemas);
3123
+ if (validationErrors.length > 0) {
3124
+ return {
3125
+ TAG: "Error",
3126
+ _0: validationErrors
3127
+ };
3128
+ }
3129
+ let warnings = collectUnionWarnings(schemas);
3130
+ let enumOccurrences = collectInlineEnums(schemas);
3131
+ let topLevelNames = schemas.map((s) => s.name);
3132
+ let enumNames = resolveEnumNames(enumOccurrences, topLevelNames);
3133
+ let enumSchemas = buildExtractedEnumSchemas(enumOccurrences, enumNames);
3134
+ let schemasAfterEnumPromotion = replaceInlineEnums(schemas, enumNames);
3135
+ let schemas$1 = enumSchemas.concat(schemasAfterEnumPromotion);
3136
+ let extractedUnions = schemas$1.flatMap((s) => extractUnions(s.name, s.schema).map((extracted) => {
3137
+ let dict = s.fieldDiscriminators;
3138
+ let discriminatorPropertyName = dict !== void 0 ? dict[extracted.name] : void 0;
3139
+ return {
3140
+ name: extracted.name,
3141
+ schema: extracted.schema,
3142
+ discriminatorTag: void 0,
3143
+ discriminatorPropertyName,
3144
+ fieldDiscriminators: void 0
3145
+ };
3146
+ }));
3147
+ let seen = {};
3148
+ let uniqueUnions = extractedUnions.filter((u) => {
3149
+ if (isSome(seen[u.name])) {
3150
+ return false;
3151
+ } else {
3152
+ seen[u.name] = true;
3153
+ return true;
3154
+ }
3155
+ });
3156
+ let modifiedSchemas = schemas$1.map((s) => ({
3157
+ name: s.name,
3158
+ schema: replaceUnions(s.name, s.schema),
3159
+ discriminatorTag: s.discriminatorTag,
3160
+ discriminatorPropertyName: s.discriminatorPropertyName,
3161
+ fieldDiscriminators: s.fieldDiscriminators
3162
+ }));
3163
+ let allSchemas = uniqueUnions.concat(modifiedSchemas);
3164
+ let schemasDict = {};
3165
+ let tagsDict = {};
3166
+ allSchemas.forEach((s) => {
3167
+ schemasDict[s.name] = s.schema;
3168
+ let tag = s.discriminatorTag;
3169
+ if (tag !== void 0) {
3170
+ tagsDict[s.name] = tag;
3171
+ return;
3172
+ }
3173
+ });
3174
+ let skipSchemaSet = buildSkipSchemaSet(allSchemas);
3175
+ let sorted = topologicalSort(allSchemas);
3176
+ let irTypes = sorted.map((s) => convertToIrTypeDef(s, schemasDict, tagsDict, skipSchemaSet));
3177
+ return {
3178
+ TAG: "Ok",
3179
+ _0: {
3180
+ preamble: "module S = Sury",
3181
+ types: irTypes,
3182
+ warnings
3183
+ }
3184
+ };
3185
+ }
3186
+
3187
+ // src/CodegenShims.mjs
3188
+ function generateDictShim() {
3189
+ return `// Generated by osury - Dict type shim for @genType
3190
+ export type t<T> = { [key: string]: T };
3191
+ `;
3192
+ }
3193
+ function generateNullableShim() {
3194
+ return `/**
3195
+ * Type shim for ReScript Nullable.t
3196
+ *
3197
+ * This file is generated by osury (not by ReScript/genType).
3198
+ * It maps ReScript's option<T> to TypeScript's T | null for JSON nullable fields.
3199
+ *
3200
+ * ReScript side: Nullable.t<T> = option<T> (works with sury's S.null schema)
3201
+ * TypeScript side: t<T> = T | null (correct JSON null representation)
3202
+ */
3203
+ export type t<T> = T | null;
3204
+ `;
3205
+ }
3206
+ function generateJsonShim() {
3207
+ return `// Generated by osury - JSON type shim for @genType
3208
+ export type t = unknown;
3209
+ `;
3210
+ }
3211
+ function generateNullableModule() {
3212
+ return `// Generated by osury - Nullable type for JSON null values
3213
+ // This is option<T> internally but maps to T | null in TypeScript via shim
3214
+ @genType.import(("./Nullable.shim.ts", "t"))
3215
+ type t<'a> = option<'a>
3216
+ `;
3217
+ }
3218
+
3219
+ // src/BackendReScript.mjs
3220
+ function quoteTag(tag) {
3221
+ let needsQuoting = tag === "" || tag.split("").some((c2) => {
3222
+ let code = c2.charCodeAt(0);
3223
+ return !(code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 95);
3224
+ });
3225
+ if (needsQuoting) {
3226
+ return `"` + tag + `"`;
3227
+ } else {
3228
+ return tag;
3229
+ }
3230
+ }
3231
+ function printPrimitive(p) {
3232
+ switch (p) {
3233
+ case "PString":
3234
+ return "string";
3235
+ case "PFloat":
3236
+ return "float";
3237
+ case "PInt":
3238
+ return "int";
3239
+ case "PBool":
3240
+ return "bool";
3241
+ case "PUnit":
3242
+ return "unit";
3243
+ }
3244
+ }
3245
+ function printType(t) {
3246
+ if (typeof t !== "object") {
3247
+ return "@s.matches(S.json) JSON.t";
3248
+ }
3249
+ switch (t.TAG) {
3250
+ case "Primitive":
3251
+ return printPrimitive(t._0);
3252
+ case "Option":
3253
+ return `option<` + printType(t._0) + `>`;
3254
+ case "Nullable":
3255
+ return `Nullable.t<` + printType(t._0) + `>`;
3256
+ case "Array":
3257
+ return `array<` + printType(t._0) + `>`;
3258
+ case "Dict":
3259
+ return `Dict.t<` + printType(t._0) + `>`;
3260
+ case "Named":
3261
+ return t._0;
3262
+ case "Enum":
3263
+ let variants = t._0.map((v) => `#` + quoteTag(v)).join(" | ");
3264
+ return `[` + variants + `]`;
3265
+ case "InlineRecord":
3266
+ return printRecord(t._0);
3267
+ case "InlineVariant":
3268
+ return printVariantCases(t._0);
3269
+ }
3270
+ }
3271
+ function printField(field) {
3272
+ let typeStr = printType(field.type_);
3273
+ let fieldType = reduce(field.annotations, typeStr, (acc, ann) => {
3274
+ if (typeof ann !== "object" && ann === "SNull") {
3275
+ return `@s.null ` + acc;
3276
+ } else {
3277
+ return acc;
3278
+ }
3279
+ });
3280
+ let asAttr = getOr(findMap(field.annotations, (ann) => {
3281
+ if (typeof ann !== "object" || ann.TAG !== "As") {
3282
+ return;
3283
+ } else {
3284
+ return `@as("` + ann._0 + `") `;
3285
+ }
3286
+ }), "");
3287
+ return asAttr + field.name + `: ` + fieldType;
3288
+ }
3289
+ function printRecord(fields) {
3290
+ if (fields.length === 0) {
3291
+ return "{}";
3292
+ }
3293
+ let fieldStrs = fields.map(printField);
3294
+ return `{
3295
+ ` + fieldStrs.join(",\n ") + `
3296
+ }`;
3297
+ }
3298
+ function printVariantCase(c2) {
3299
+ let payloadStr = printType(c2.payload);
3300
+ return c2.tag + `(` + payloadStr + `)`;
3301
+ }
3302
+ function printVariantCases(cases) {
3303
+ let caseStrs = cases.map(printVariantCase);
3304
+ return `[` + caseStrs.map((c2) => `#` + quoteTag(c2)).join(" | ") + `]`;
3305
+ }
3306
+ function printAnnotation(ann) {
3307
+ if (typeof ann === "object") {
3308
+ if (ann.TAG === "Tag") {
3309
+ return `@tag("` + ann._0 + `")`;
3310
+ } else {
3311
+ return;
3312
+ }
3313
+ }
3314
+ switch (ann) {
3315
+ case "GenType":
3316
+ return "@genType";
3317
+ case "Schema":
3318
+ return "@schema";
3319
+ case "Unboxed":
3320
+ return "@unboxed";
3321
+ case "SNull":
3322
+ return;
3323
+ }
3324
+ }
3325
+ function printAnnotations(annotations) {
3326
+ return filterMap(annotations, printAnnotation).join("\n");
3327
+ }
3328
+ function printTypeDef(typeDef) {
3329
+ let annotations = printAnnotations(typeDef.annotations);
3330
+ let fields = typeDef.kind;
3331
+ let body;
3332
+ switch (fields.TAG) {
3333
+ case "RecordDef":
3334
+ body = printRecord(fields._0);
3335
+ break;
3336
+ case "VariantDef":
3337
+ body = fields._0.map(printVariantCase).join(" | ");
3338
+ break;
3339
+ case "AliasDef":
3340
+ body = printType(fields._0);
3341
+ break;
3342
+ }
3343
+ return annotations + `
3344
+ type ` + typeDef.name + ` = ` + body;
3345
+ }
3346
+ function print(module_) {
3347
+ let typeDefs = module_.types.map(printTypeDef).join("\n\n");
3348
+ return module_.preamble + "\n\n" + typeDefs;
3349
+ }
3350
+
3351
+ // src/Codegen.mjs
3352
+ function generateModuleWithDiagnostics(schemas) {
3353
+ let irModule = generate(schemas);
3354
+ if (irModule.TAG !== "Ok") {
3355
+ return {
3356
+ TAG: "Error",
3357
+ _0: irModule._0
3358
+ };
3359
+ }
3360
+ let irModule$1 = irModule._0;
3361
+ let code = print(irModule$1);
3362
+ return {
3363
+ TAG: "Ok",
3364
+ _0: {
3365
+ code,
3366
+ warnings: irModule$1.warnings
3367
+ }
3368
+ };
3369
+ }
3370
+ var generateDictShim2 = generateDictShim;
3371
+ var generateJsonShim2 = generateJsonShim;
3372
+ var generateNullableShim2 = generateNullableShim;
3373
+ var generateNullableModule2 = generateNullableModule;
3374
+
3375
+ // src/DomainConfig.mjs
3376
+ function parseFieldConfig(name, json) {
3377
+ if (typeof json === "object" && json !== null && !Array.isArray(json)) {
3378
+ let match = json["type"];
3379
+ let exit = 0;
3380
+ if (match !== void 0) {
3381
+ if (typeof match === "string") {
3382
+ let match$1 = json["mapper"];
3383
+ let mapper = typeof match$1 === "string" ? match$1 : void 0;
3384
+ let match$2 = json["source"];
3385
+ let source = typeof match$2 === "string" ? match$2 : void 0;
3386
+ return {
3387
+ TAG: "Ok",
3388
+ _0: [
3389
+ name,
3390
+ {
3391
+ type_: match,
3392
+ mapper,
3393
+ source
3394
+ }
3395
+ ]
3396
+ };
3397
+ }
3398
+ exit = 2;
3399
+ } else {
3400
+ exit = 2;
3401
+ }
3402
+ if (exit === 2) {
3403
+ return {
3404
+ TAG: "Error",
3405
+ _0: [makeError({
3406
+ TAG: "MissingRequiredField",
3407
+ _0: "type"
3408
+ }, [
3409
+ "fields",
3410
+ name
3411
+ ], some(`Field "` + name + `" must have a "type" property`), void 0)]
3412
+ };
3413
+ }
3414
+ }
3415
+ return {
3416
+ TAG: "Error",
3417
+ _0: [makeError({
3418
+ TAG: "InvalidJson",
3419
+ _0: `field "` + name + `" must be an object`
3420
+ }, [
3421
+ "fields",
3422
+ name
3423
+ ], void 0, void 0)]
3424
+ };
3425
+ }
3426
+ function parseModuleConfig(name, json) {
3427
+ if (typeof json === "object" && json !== null && !Array.isArray(json)) {
3428
+ let match = json["source"];
3429
+ let exit = 0;
3430
+ if (typeof match === "string") {
3431
+ let match$1 = json["output"];
3432
+ let output = typeof match$1 === "string" ? match$1 : void 0;
3433
+ let match$2 = json["fields"];
3434
+ let exit$1 = 0;
3435
+ if (match$2 !== void 0) {
3436
+ if (typeof match$2 === "object" && match$2 !== null && !Array.isArray(match$2)) {
3437
+ let entries = Object.entries(match$2);
3438
+ let results = entries.map((param) => parseFieldConfig(param[0], param[1]));
3439
+ let errors = filterMap(results, (r) => {
3440
+ if (r.TAG === "Ok") {
3441
+ return;
3442
+ } else {
3443
+ return r._0;
3444
+ }
3445
+ }).flat();
3446
+ if (errors.length > 0) {
3447
+ return {
3448
+ TAG: "Error",
3449
+ _0: errors
3450
+ };
3451
+ }
3452
+ let fields = filterMap(results, (r) => {
3453
+ if (r.TAG === "Ok") {
3454
+ return r._0;
3455
+ }
3456
+ });
3457
+ return {
3458
+ TAG: "Ok",
3459
+ _0: [
3460
+ name,
3461
+ {
3462
+ source: match,
3463
+ output,
3464
+ fields
3465
+ }
3466
+ ]
3467
+ };
3468
+ }
3469
+ exit$1 = 3;
3470
+ } else {
3471
+ exit$1 = 3;
3472
+ }
3473
+ if (exit$1 === 3) {
3474
+ return {
3475
+ TAG: "Error",
3476
+ _0: [makeError({
3477
+ TAG: "MissingRequiredField",
3478
+ _0: "fields"
3479
+ }, [
3480
+ "modules",
3481
+ name
3482
+ ], some(`Module "` + name + `" must have a "fields" object`), void 0)]
3483
+ };
3484
+ }
3485
+ } else {
3486
+ exit = 2;
3487
+ }
3488
+ if (exit === 2) {
3489
+ return {
3490
+ TAG: "Error",
3491
+ _0: [makeError({
3492
+ TAG: "MissingRequiredField",
3493
+ _0: "source"
3494
+ }, [
3495
+ "modules",
3496
+ name
3497
+ ], some(`Module "` + name + `" must have a "source" property referencing the API type`), void 0)]
3498
+ };
3499
+ }
3500
+ }
3501
+ return {
3502
+ TAG: "Error",
3503
+ _0: [makeError({
3504
+ TAG: "InvalidJson",
3505
+ _0: `module "` + name + `" must be an object`
3506
+ }, [
3507
+ "modules",
3508
+ name
3509
+ ], void 0, void 0)]
3510
+ };
3511
+ }
3512
+ function parse2(json) {
3513
+ if (typeof json === "object" && json !== null && !Array.isArray(json)) {
3514
+ let match = json["modules"];
3515
+ let exit = 0;
3516
+ if (match !== void 0) {
3517
+ if (typeof match === "object" && match !== null && !Array.isArray(match)) {
3518
+ let entries = Object.entries(match);
3519
+ let results = entries.map((param) => parseModuleConfig(param[0], param[1]));
3520
+ let errors = filterMap(results, (r) => {
3521
+ if (r.TAG === "Ok") {
3522
+ return;
3523
+ } else {
3524
+ return r._0;
3525
+ }
3526
+ }).flat();
3527
+ if (errors.length > 0) {
3528
+ return {
3529
+ TAG: "Error",
3530
+ _0: errors
3531
+ };
3532
+ }
3533
+ let modules = filterMap(results, (r) => {
3534
+ if (r.TAG === "Ok") {
3535
+ return r._0;
3536
+ }
3537
+ });
3538
+ return {
3539
+ TAG: "Ok",
3540
+ _0: {
3541
+ modules
3542
+ }
3543
+ };
3544
+ }
3545
+ exit = 2;
3546
+ } else {
3547
+ exit = 2;
3548
+ }
3549
+ if (exit === 2) {
3550
+ return {
3551
+ TAG: "Error",
3552
+ _0: [makeError({
3553
+ TAG: "MissingRequiredField",
3554
+ _0: "modules"
3555
+ }, [], `Config must have a "modules" object`, void 0)]
3556
+ };
3557
+ }
3558
+ }
3559
+ return {
3560
+ TAG: "Error",
3561
+ _0: [makeError({
3562
+ TAG: "InvalidJson",
3563
+ _0: "config must be an object"
3564
+ }, void 0, void 0, void 0)]
3565
+ };
3566
+ }
3567
+
3568
+ // src/DomainGen.mjs
3569
+ function generateField(param) {
3570
+ let fieldConfig = param[1];
3571
+ let name = param[0];
3572
+ let mapper = fieldConfig.mapper;
3573
+ let mapping;
3574
+ if (mapper !== void 0) {
3575
+ mapping = {
3576
+ TAG: "Mapper",
3577
+ _0: mapper
3578
+ };
3579
+ } else {
3580
+ let s = fieldConfig.source;
3581
+ let sourceName = s !== void 0 ? s : name;
3582
+ mapping = {
3583
+ TAG: "Passthrough",
3584
+ _0: sourceName
3585
+ };
3586
+ }
3587
+ return {
3588
+ name,
3589
+ typeAnnotation: fieldConfig.type_,
3590
+ mapping
3591
+ };
3592
+ }
3593
+ function generateModule(param, apiModule) {
3594
+ let moduleConfig = param[1];
3595
+ let name = param[0];
3596
+ let o = moduleConfig.output;
3597
+ let output = o !== void 0 ? o : name + ".gen.res";
3598
+ let sourceType = apiModule + "." + moduleConfig.source;
3599
+ let fields = moduleConfig.fields.map(generateField);
3600
+ return {
3601
+ name,
3602
+ sourceType,
3603
+ output,
3604
+ fields
3605
+ };
3606
+ }
3607
+ function generate2(config, apiModule) {
3608
+ return config.modules.map((entry) => generateModule(entry, apiModule));
3609
+ }
3610
+
3611
+ // src/DomainBackend.mjs
3612
+ function printField2(field) {
3613
+ return ` ` + field.name + `: ` + field.typeAnnotation + `,`;
3614
+ }
3615
+ function printType2(module_) {
3616
+ let fields = module_.fields.map(printField2).join("\n");
3617
+ return `type t = {
3618
+ ` + fields + `
3619
+ }`;
3620
+ }
3621
+ function printMakeField(field) {
3622
+ let fn = field.mapping;
3623
+ if (fn.TAG === "Mapper") {
3624
+ return ` ` + field.name + `: ` + fn._0 + `(raw),`;
3625
+ } else {
3626
+ return ` ` + field.name + `: raw.` + fn._0 + `,`;
3627
+ }
3628
+ }
3629
+ function printMake(module_) {
3630
+ let fields = module_.fields.map(printMakeField).join("\n");
3631
+ return `let make = (raw: ` + module_.sourceType + `): t => {
3632
+ ` + fields + `
3633
+ }`;
3634
+ }
3635
+ function printModule(module_) {
3636
+ let header2 = `// ` + module_.output + ` (generated by osury \u2014 do not edit)`;
3637
+ let typeBlock = printType2(module_);
3638
+ let makeBlock = printMake(module_);
3639
+ return header2 + "\n\n" + typeBlock + "\n\n" + makeBlock + "\n";
3640
+ }
3641
+
3642
+ // bin/osury.mjs
3643
+ import fs from "fs";
3644
+ import path from "path";
3645
+ import { createRequire } from "module";
3646
+ import { performance } from "perf_hooks";
3647
+ var require2 = createRequire(import.meta.url);
3648
+ var pkg = require2("../package.json");
3649
+ var VERSION = pkg.version;
3650
+ var noColor = process.env.NO_COLOR != null || process.argv.includes("--no-color") || !process.stderr.isTTY;
3651
+ var fmt = (code, text) => noColor ? text : `\x1B[${code}m${text}\x1B[0m`;
3652
+ var c = {
3653
+ bold: (t) => fmt("1", t),
3654
+ dim: (t) => fmt("2", t),
3655
+ italic: (t) => fmt("3", t),
3656
+ red: (t) => fmt("31", t),
3657
+ green: (t) => fmt("32", t),
3658
+ yellow: (t) => fmt("33", t),
3659
+ blue: (t) => fmt("34", t),
3660
+ magenta: (t) => fmt("35", t),
3661
+ cyan: (t) => fmt("36", t),
3662
+ white: (t) => fmt("37", t),
3663
+ gray: (t) => fmt("90", t),
3664
+ boldRed: (t) => fmt("1;31", t),
3665
+ boldGreen: (t) => fmt("1;32", t),
3666
+ boldYellow: (t) => fmt("1;33", t),
3667
+ boldCyan: (t) => fmt("1;36", t)
3668
+ };
3669
+ var sym = {
3670
+ success: c.green("\u2713"),
3671
+ error: c.red("\u2717"),
3672
+ warning: c.yellow("\u26A0"),
3673
+ arrow: c.dim("\u2192"),
3674
+ bullet: c.dim("\xB7"),
3675
+ bar: c.dim("\u2502")
3676
+ };
3677
+ var log = (...args) => console.log(...args);
3678
+ var err = (...args) => console.error(...args);
3679
+ var blank = () => log();
3680
+ function header() {
3681
+ blank();
3682
+ log(` ${c.bold("osury")} ${c.dim(`v${VERSION}`)}`);
3683
+ log(` ${c.dim("OpenAPI 3.x \u2192 ReScript + Sury")}`);
3684
+ blank();
3685
+ }
3686
+ function elapsed(startMs) {
3687
+ const ms = performance.now() - startMs;
3688
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
3689
+ return `${(ms / 1e3).toFixed(2)}s`;
3690
+ }
3691
+ function printHelp() {
3692
+ header();
3693
+ log(` ${c.bold("Usage")}`);
3694
+ log(` ${c.cyan("$")} osury ${c.cyan("<input.json>")} ${c.dim("[output.res]")}`);
3695
+ log(` ${c.cyan("$")} osury generate ${c.cyan("<input.json>")} -o ${c.cyan("<output.res>")}`);
3696
+ log(` ${c.cyan("$")} osury domain ${c.dim("[options]")}`);
3697
+ blank();
3698
+ log(` ${c.bold("Options")}`);
3699
+ log(` ${c.cyan("-o")}, ${c.cyan("--output")} Output file path ${c.dim("(default: ./Generated.res)")}`);
3700
+ log(` ${c.cyan("-h")}, ${c.cyan("--help")} Show this help`);
3701
+ log(` ${c.cyan("-v")}, ${c.cyan("--version")} Show version`);
3702
+ log(` ${c.cyan("--no-color")} Disable colored output`);
3703
+ blank();
3704
+ log(` ${c.bold("Domain options")}`);
3705
+ log(` ${c.cyan("--config")} Config file path ${c.dim("(default: domain.config.json)")}`);
3706
+ log(` ${c.cyan("--api-module")} API module name ${c.dim("(default: Api)")}`);
3707
+ log(` ${c.cyan("-o")} Output directory ${c.dim("(default: src/domains/)")}`);
3708
+ blank();
3709
+ log(` ${c.bold("Examples")}`);
3710
+ log(` ${c.cyan("$")} osury openapi.json`);
3711
+ log(` ${c.cyan("$")} osury openapi.json src/API.res`);
3712
+ log(` ${c.cyan("$")} osury generate schema.json -o src/Schema.res`);
3713
+ log(` ${c.cyan("$")} osury domain --config domain.config.json --api-module Api`);
3714
+ blank();
3715
+ }
3716
+ function parseArgs(args) {
3717
+ const options = { input: null, output: "./Generated.res" };
3718
+ let i = 0;
3719
+ while (i < args.length) {
3720
+ const arg = args[i];
3721
+ if (arg === "-h" || arg === "--help") {
3722
+ printHelp();
3723
+ process.exit(0);
3724
+ } else if (arg === "-v" || arg === "--version") {
3725
+ log(`osury v${VERSION}`);
3726
+ process.exit(0);
3727
+ } else if (arg === "--no-color") {
3728
+ } else if (arg === "-o" || arg === "--output") {
3729
+ i++;
3730
+ if (i >= args.length) {
3731
+ header();
3732
+ err(` ${sym.error} ${c.boldRed("Missing value for --output")}`);
3733
+ blank();
3734
+ err(` Expected: osury input.json ${c.cyan("-o <path>")}`);
3735
+ blank();
3736
+ process.exit(1);
3737
+ }
3738
+ options.output = args[i];
3739
+ } else if (arg === "generate") {
3740
+ } else if (!options.input) {
3741
+ options.input = arg;
3742
+ } else if (options.output === "./Generated.res") {
3743
+ options.output = arg;
3744
+ }
3745
+ i++;
3746
+ }
3747
+ return options;
3748
+ }
3749
+ function levenshtein(a, b) {
3750
+ const m = a.length, n = b.length;
3751
+ const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
3752
+ for (let i = 0; i <= m; i++) dp[i][0] = i;
3753
+ for (let j = 0; j <= n; j++) dp[0][j] = j;
3754
+ for (let i = 1; i <= m; i++)
3755
+ for (let j = 1; j <= n; j++)
3756
+ dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
3757
+ return dp[m][n];
3758
+ }
3759
+ function findSimilarFiles(target) {
3760
+ const dir = path.dirname(target);
3761
+ const resolvedDir = dir === "." ? process.cwd() : dir;
3762
+ const base = path.basename(target).toLowerCase();
3763
+ try {
3764
+ const files = fs.readdirSync(resolvedDir);
3765
+ return files.filter((f) => {
3766
+ const fl = f.toLowerCase();
3767
+ if (!fl.endsWith(".json") && !fl.endsWith(".yaml") && !fl.endsWith(".yml"))
3768
+ return false;
3769
+ return levenshtein(base, fl) <= Math.ceil(base.length * 0.4);
3770
+ }).sort((a, b) => levenshtein(a.toLowerCase(), base) - levenshtein(b.toLowerCase(), base)).slice(0, 3);
3771
+ } catch {
3772
+ return [];
3773
+ }
3774
+ }
3775
+ function formatErrorKind(kind) {
3776
+ if (!kind || !kind.TAG) return "Unknown error";
3777
+ switch (kind.TAG) {
3778
+ case "UnknownType":
3779
+ return `Unknown type ${c.bold(`"${kind._0}"`)}`;
3780
+ case "MissingRequiredField":
3781
+ return `Missing required field ${c.bold(`"${kind._0}"`)}`;
3782
+ case "InvalidRef":
3783
+ return `Invalid reference ${c.bold(`"${kind._0}"`)}`;
3784
+ case "UnsupportedFeature":
3785
+ return `Unsupported feature ${c.bold(`"${kind._0}"`)}`;
3786
+ case "InvalidFormat":
3787
+ return `Invalid format ${c.bold(`"${kind._0}"`)}`;
3788
+ case "CircularReference":
3789
+ return `Circular reference ${c.bold(`"${kind._0}"`)}`;
3790
+ case "AmbiguousUnion":
3791
+ return `Ambiguous union (anyOf/oneOf cannot be distinguished)`;
3792
+ case "MissingDiscriminator":
3793
+ return `Missing discriminator for union ${c.bold(`"${kind._0}"`)}`;
3794
+ case "InvalidJson":
3795
+ return `Invalid JSON: ${kind._0}`;
3796
+ default:
3797
+ return kind.TAG + (kind._0 ? `: ${kind._0}` : "");
3798
+ }
3799
+ }
3800
+ function formatParseError(error, index) {
3801
+ const pathStr = error.location?.path?.length > 0 ? c.cyan("#/" + error.location.path.join("/")) : c.cyan("#");
3802
+ const lines = [];
3803
+ lines.push(` ${c.dim(`${index + 1}.`)} ${pathStr}`);
3804
+ lines.push(` ${formatErrorKind(error.kind)}`);
3805
+ if (error.hint) {
3806
+ lines.push(` ${c.dim("Hint:")} ${c.italic(error.hint)}`);
3807
+ }
3808
+ return lines.join("\n");
3809
+ }
3810
+ function formatWarning(warning) {
3811
+ const cleaned = warning.replace(/^⚠\s*/, "");
3812
+ return ` ${sym.warning} ${c.yellow(cleaned)}`;
3813
+ }
3814
+ function generate3(inputPath, outputPath) {
3815
+ const start = performance.now();
3816
+ header();
3817
+ if (!fs.existsSync(inputPath)) {
3818
+ err(` ${sym.error} ${c.boldRed("File not found:")} ${c.cyan(inputPath)}`);
3819
+ const similar = findSimilarFiles(inputPath);
3820
+ if (similar.length > 0) {
3821
+ blank();
3822
+ err(` ${c.dim("Did you mean?")}`);
3823
+ similar.forEach((f) => {
3824
+ err(` ${sym.bullet} ${c.cyan(f)}`);
3825
+ });
3826
+ }
3827
+ blank();
3828
+ process.exit(1);
3829
+ }
3830
+ let doc;
3831
+ try {
3832
+ const raw = fs.readFileSync(inputPath, "utf8");
3833
+ doc = JSON.parse(raw);
3834
+ } catch (e) {
3835
+ err(` ${sym.error} ${c.boldRed("Invalid JSON")} in ${c.cyan(inputPath)}`);
3836
+ blank();
3837
+ if (e instanceof SyntaxError) {
3838
+ const msg = e.message.replace(/^Unexpected/, "Unexpected");
3839
+ err(` ${c.red(msg)}`);
3840
+ } else {
3841
+ err(` ${c.red(e.message)}`);
3842
+ }
3843
+ blank();
3844
+ err(` ${c.dim("Tip:")} Validate your JSON at ${c.cyan("https://jsonlint.com")}`);
3845
+ blank();
3846
+ process.exit(1);
3847
+ }
3848
+ const result = parseDocument(doc);
3849
+ if (result.TAG !== "Ok") {
3850
+ const errors = result._0;
3851
+ const count = errors.length;
3852
+ err(
3853
+ ` ${sym.error} ${c.boldRed(`${count} parse error${count !== 1 ? "s" : ""}`)} in ${c.cyan(inputPath)}`
3854
+ );
3855
+ blank();
3856
+ errors.forEach((error, i) => {
3857
+ err(formatParseError(error, i));
3858
+ if (i < errors.length - 1) blank();
3859
+ });
3860
+ blank();
3861
+ process.exit(1);
3862
+ }
3863
+ const schemas = result._0;
3864
+ const schemaCount = schemas.length;
3865
+ log(` ${sym.success} Parsed ${c.bold(String(schemaCount))} schema${schemaCount !== 1 ? "s" : ""} from ${c.cyan(inputPath)}`);
3866
+ const genResult = generateModuleWithDiagnostics(schemas);
3867
+ if (genResult.TAG !== "Ok") {
3868
+ const errors = genResult._0;
3869
+ const count = errors.length;
3870
+ err(
3871
+ ` ${sym.error} ${c.boldRed(`${count} codegen error${count !== 1 ? "s" : ""}`)} in ${c.cyan(inputPath)}`
3872
+ );
3873
+ blank();
3874
+ errors.forEach((error, i) => {
3875
+ err(formatParseError(error, i));
3876
+ if (i < errors.length - 1) blank();
3877
+ });
3878
+ blank();
3879
+ process.exit(1);
3880
+ }
3881
+ const { code, warnings } = genResult._0;
3882
+ if (warnings.length > 0) {
3883
+ blank();
3884
+ warnings.forEach((w) => {
3885
+ log(formatWarning(w));
3886
+ });
3887
+ }
3888
+ const outputDir = path.dirname(outputPath);
3889
+ if (outputDir && outputDir !== "." && !fs.existsSync(outputDir)) {
3890
+ fs.mkdirSync(outputDir, { recursive: true });
3891
+ }
3892
+ const typeCount = (code.match(/^type\s/gm) || []).length;
3893
+ fs.writeFileSync(outputPath, code);
3894
+ const dictShimPath = path.join(outputDir || ".", "Dict.gen.ts");
3895
+ fs.writeFileSync(dictShimPath, generateDictShim2());
3896
+ const jsonShimPath = path.join(outputDir || ".", "JSON.gen.ts");
3897
+ fs.writeFileSync(jsonShimPath, generateJsonShim2());
3898
+ const nullableResPath = path.join(outputDir || ".", "Nullable.res");
3899
+ fs.writeFileSync(nullableResPath, generateNullableModule2());
3900
+ const nullableShimPath = path.join(outputDir || ".", "Nullable.shim.ts");
3901
+ fs.writeFileSync(nullableShimPath, generateNullableShim2());
3902
+ blank();
3903
+ log(` ${sym.success} Generated ${c.bold(String(typeCount))} type${typeCount !== 1 ? "s" : ""}`);
3904
+ blank();
3905
+ log(` ${c.dim("Files written:")}`);
3906
+ log(` ${sym.bullet} ${c.cyan(outputPath)} ${c.dim("(main module)")}`);
3907
+ log(` ${sym.bullet} ${c.cyan(dictShimPath)} ${c.dim("(TS shim)")}`);
3908
+ log(` ${sym.bullet} ${c.cyan(jsonShimPath)} ${c.dim("(TS shim)")}`);
3909
+ log(` ${sym.bullet} ${c.cyan(nullableResPath)} ${c.dim("(ReScript module)")}`);
3910
+ log(` ${sym.bullet} ${c.cyan(nullableShimPath)} ${c.dim("(TS shim)")}`);
3911
+ blank();
3912
+ log(` ${c.dim(`Done in ${elapsed(start)}`)}`);
3913
+ blank();
3914
+ }
3915
+ function parseDomainArgs(args) {
3916
+ const options = {
3917
+ config: "domain.config.json",
3918
+ apiModule: "Api",
3919
+ outputDir: "src/domains/"
3920
+ };
3921
+ let i = 0;
3922
+ while (i < args.length) {
3923
+ const arg = args[i];
3924
+ if (arg === "-h" || arg === "--help") {
3925
+ printHelp();
3926
+ process.exit(0);
3927
+ } else if (arg === "--config") {
3928
+ i++;
3929
+ if (i >= args.length) {
3930
+ header();
3931
+ err(` ${sym.error} ${c.boldRed("Missing value for --config")}`);
3932
+ blank();
3933
+ process.exit(1);
3934
+ }
3935
+ options.config = args[i];
3936
+ } else if (arg === "--api-module") {
3937
+ i++;
3938
+ if (i >= args.length) {
3939
+ header();
3940
+ err(` ${sym.error} ${c.boldRed("Missing value for --api-module")}`);
3941
+ blank();
3942
+ process.exit(1);
3943
+ }
3944
+ options.apiModule = args[i];
3945
+ } else if (arg === "-o" || arg === "--output") {
3946
+ i++;
3947
+ if (i >= args.length) {
3948
+ header();
3949
+ err(` ${sym.error} ${c.boldRed("Missing value for --output")}`);
3950
+ blank();
3951
+ process.exit(1);
3952
+ }
3953
+ options.outputDir = args[i];
3954
+ } else if (arg === "--no-color") {
3955
+ }
3956
+ i++;
3957
+ }
3958
+ return options;
3959
+ }
3960
+ function generateDomain(options) {
3961
+ const start = performance.now();
3962
+ header();
3963
+ log(` ${c.dim("Mode:")} domain module generation`);
3964
+ blank();
3965
+ if (!fs.existsSync(options.config)) {
3966
+ err(` ${sym.error} ${c.boldRed("Config not found:")} ${c.cyan(options.config)}`);
3967
+ blank();
3968
+ process.exit(1);
3969
+ }
3970
+ let configJson;
3971
+ try {
3972
+ const raw = fs.readFileSync(options.config, "utf8");
3973
+ configJson = JSON.parse(raw);
3974
+ } catch (e) {
3975
+ err(` ${sym.error} ${c.boldRed("Invalid JSON")} in ${c.cyan(options.config)}`);
3976
+ blank();
3977
+ if (e instanceof SyntaxError) {
3978
+ err(` ${c.red(e.message)}`);
3979
+ } else {
3980
+ err(` ${c.red(e.message)}`);
3981
+ }
3982
+ blank();
3983
+ process.exit(1);
3984
+ }
3985
+ const parseResult = parse2(configJson);
3986
+ if (parseResult.TAG !== "Ok") {
3987
+ const errors = parseResult._0;
3988
+ const count = errors.length;
3989
+ err(
3990
+ ` ${sym.error} ${c.boldRed(`${count} config error${count !== 1 ? "s" : ""}`)} in ${c.cyan(options.config)}`
3991
+ );
3992
+ blank();
3993
+ errors.forEach((error, i) => {
3994
+ err(formatParseError(error, i));
3995
+ if (i < errors.length - 1) blank();
3996
+ });
3997
+ blank();
3998
+ process.exit(1);
3999
+ }
4000
+ const config = parseResult._0;
4001
+ const moduleCount = config.modules.length;
4002
+ log(` ${sym.success} Parsed ${c.bold(String(moduleCount))} domain module${moduleCount !== 1 ? "s" : ""} from ${c.cyan(options.config)}`);
4003
+ const modules = generate2(config, options.apiModule);
4004
+ if (!fs.existsSync(options.outputDir)) {
4005
+ fs.mkdirSync(options.outputDir, { recursive: true });
4006
+ }
4007
+ const writtenFiles = [];
4008
+ modules.forEach((mod) => {
4009
+ const code = printModule(mod);
4010
+ const outputPath = path.join(options.outputDir, mod.output);
4011
+ fs.writeFileSync(outputPath, code);
4012
+ writtenFiles.push(outputPath);
4013
+ });
4014
+ blank();
4015
+ log(` ${sym.success} Generated ${c.bold(String(writtenFiles.length))} domain module${writtenFiles.length !== 1 ? "s" : ""}`);
4016
+ blank();
4017
+ log(` ${c.dim("Files written:")}`);
4018
+ writtenFiles.forEach((f) => {
4019
+ log(` ${sym.bullet} ${c.cyan(f)}`);
4020
+ });
4021
+ blank();
4022
+ log(` ${c.dim(`Done in ${elapsed(start)}`)}`);
4023
+ blank();
4024
+ }
4025
+ var rawArgs = process.argv.slice(2);
4026
+ if (rawArgs[0] === "domain") {
4027
+ const domainOptions = parseDomainArgs(rawArgs.slice(1));
4028
+ generateDomain(domainOptions);
4029
+ } else {
4030
+ const options = parseArgs(rawArgs);
4031
+ if (!options.input) {
4032
+ header();
4033
+ err(` ${sym.error} ${c.boldRed("No input file specified")}`);
4034
+ blank();
4035
+ err(` ${c.dim("Usage:")} osury ${c.cyan("<input.json>")} ${c.dim("[output.res]")}`);
4036
+ err(` ${c.dim("Help:")} osury ${c.cyan("--help")}`);
4037
+ blank();
4038
+ process.exit(1);
4039
+ }
4040
+ generate3(options.input, options.output);
4041
+ }