osury 0.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.
@@ -0,0 +1,578 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Core__Option from "@rescript/core/src/Core__Option.res.mjs";
4
+
5
+ let reservedKeywords = [
6
+ "type",
7
+ "let",
8
+ "rec",
9
+ "and",
10
+ "as",
11
+ "open",
12
+ "include",
13
+ "module",
14
+ "sig",
15
+ "struct",
16
+ "exception",
17
+ "external",
18
+ "if",
19
+ "else",
20
+ "switch",
21
+ "while",
22
+ "for",
23
+ "try",
24
+ "catch",
25
+ "when",
26
+ "true",
27
+ "false",
28
+ "assert",
29
+ "lazy",
30
+ "constraint",
31
+ "functor",
32
+ "class",
33
+ "method",
34
+ "object",
35
+ "private",
36
+ "public",
37
+ "virtual",
38
+ "mutable",
39
+ "new",
40
+ "inherit",
41
+ "initializer",
42
+ "val",
43
+ "with",
44
+ "match",
45
+ "of",
46
+ "fun",
47
+ "function",
48
+ "in",
49
+ "do",
50
+ "done",
51
+ "begin",
52
+ "end",
53
+ "then",
54
+ "to",
55
+ "downto",
56
+ "or",
57
+ "land",
58
+ "lor",
59
+ "lxor",
60
+ "lsl",
61
+ "lsr",
62
+ "asr",
63
+ "mod",
64
+ "await",
65
+ "async"
66
+ ];
67
+
68
+ function isReservedKeyword(name) {
69
+ return reservedKeywords.includes(name);
70
+ }
71
+
72
+ function lcFirst(s) {
73
+ if (s.length === 0) {
74
+ return s;
75
+ }
76
+ let first = s.charAt(0).toLowerCase();
77
+ let rest = s.slice(1);
78
+ return first + rest;
79
+ }
80
+
81
+ function generateType(schema) {
82
+ if (typeof schema !== "object") {
83
+ switch (schema) {
84
+ case "String" :
85
+ return "string";
86
+ case "Number" :
87
+ return "float";
88
+ case "Integer" :
89
+ return "int";
90
+ case "Boolean" :
91
+ return "bool";
92
+ case "Null" :
93
+ return "unit";
94
+ }
95
+ } else {
96
+ switch (schema._tag) {
97
+ case "Optional" :
98
+ return `option<` + generateType(schema._0) + `>`;
99
+ case "Object" :
100
+ return generateRecord(schema._0);
101
+ case "Array" :
102
+ return `array<` + generateType(schema._0) + `>`;
103
+ case "Ref" :
104
+ return lcFirst(schema._0);
105
+ case "Enum" :
106
+ let variants = schema._0.map(v => `#` + v).join(" | ");
107
+ return `[` + variants + `]`;
108
+ case "PolyVariant" :
109
+ return generatePolyVariant(schema._0);
110
+ case "Dict" :
111
+ return `Dict.t<` + generateType(schema._0) + `>`;
112
+ case "Union" :
113
+ return generateUnion(schema._0);
114
+ }
115
+ }
116
+ }
117
+
118
+ function isOptionalType(schema) {
119
+ if (typeof schema !== "object") {
120
+ return false;
121
+ } else {
122
+ return schema._tag === "Optional";
123
+ }
124
+ }
125
+
126
+ function generateRecord(fields) {
127
+ if (fields.length === 0) {
128
+ return "{}";
129
+ }
130
+ let fieldStrs = fields.map(field => {
131
+ let typeStr = generateType(field.type);
132
+ let optionalType = field.required || isOptionalType(field.type) ? typeStr : `option<` + typeStr + `>`;
133
+ if (reservedKeywords.includes(field.name)) {
134
+ return `@as("` + field.name + `") ` + field.name + `_: ` + optionalType;
135
+ } else {
136
+ return field.name + `: ` + optionalType;
137
+ }
138
+ });
139
+ return `{\n ` + fieldStrs.join(",\n ") + `\n}`;
140
+ }
141
+
142
+ function generatePolyVariant(cases) {
143
+ let caseStrs = cases.map(c => {
144
+ let payloadStr = generateType(c.payload);
145
+ return `#` + c._tag + `(` + payloadStr + `)`;
146
+ });
147
+ return `[` + caseStrs.join(" | ") + `]`;
148
+ }
149
+
150
+ function ucFirst(s) {
151
+ if (s.length === 0) {
152
+ return s;
153
+ }
154
+ let first = s.charAt(0).toUpperCase();
155
+ let rest = s.slice(1);
156
+ return first + rest;
157
+ }
158
+
159
+ function getTagForType(t) {
160
+ if (typeof t !== "object") {
161
+ switch (t) {
162
+ case "String" :
163
+ return "String";
164
+ case "Number" :
165
+ return "Float";
166
+ case "Integer" :
167
+ return "Int";
168
+ case "Boolean" :
169
+ return "Bool";
170
+ case "Null" :
171
+ return "Null";
172
+ }
173
+ } else {
174
+ switch (t._tag) {
175
+ case "Optional" :
176
+ return `Option` + getTagForType(t._0);
177
+ case "Object" :
178
+ return "Object";
179
+ case "Array" :
180
+ return `Array` + getTagForType(t._0);
181
+ case "Ref" :
182
+ return ucFirst(t._0);
183
+ case "Enum" :
184
+ return "Enum";
185
+ case "PolyVariant" :
186
+ return "Variant";
187
+ case "Dict" :
188
+ return "Dict";
189
+ case "Union" :
190
+ return "Union";
191
+ }
192
+ }
193
+ }
194
+
195
+ function generateUnion(types) {
196
+ let caseStrs = types.map(t => {
197
+ let tag = getTagForType(t);
198
+ let payload = generateType(t);
199
+ return `#` + tag + `(` + payload + `)`;
200
+ });
201
+ return `[` + caseStrs.join(" | ") + `]`;
202
+ }
203
+
204
+ function hasUnion(_schema) {
205
+ while (true) {
206
+ let schema = _schema;
207
+ if (typeof schema !== "object") {
208
+ return false;
209
+ }
210
+ switch (schema._tag) {
211
+ case "Object" :
212
+ return schema._0.some(f => hasUnion(f.type));
213
+ case "PolyVariant" :
214
+ return schema._0.some(c => hasUnion(c.payload));
215
+ case "Optional" :
216
+ case "Array" :
217
+ case "Dict" :
218
+ _schema = schema._0;
219
+ continue;
220
+ case "Union" :
221
+ return true;
222
+ default:
223
+ return false;
224
+ }
225
+ };
226
+ }
227
+
228
+ function getUnionName(types) {
229
+ let names = types.map(t => {
230
+ if (typeof t !== "object") {
231
+ switch (t) {
232
+ case "String" :
233
+ return "string";
234
+ case "Number" :
235
+ return "float";
236
+ case "Integer" :
237
+ return "int";
238
+ case "Boolean" :
239
+ return "bool";
240
+ case "Null" :
241
+ return "null";
242
+ }
243
+ } else {
244
+ switch (t._tag) {
245
+ case "Array" :
246
+ return "array";
247
+ case "Ref" :
248
+ return lcFirst(t._0);
249
+ case "Dict" :
250
+ return "dict";
251
+ default:
252
+ return "unknown";
253
+ }
254
+ }
255
+ });
256
+ if (names.length === 0) {
257
+ return "emptyUnion";
258
+ }
259
+ let first = Core__Option.getOr(names[0], "unknown");
260
+ let rest = names.slice(1);
261
+ return first + rest.map(n => "Or" + ucFirst(n)).join("");
262
+ }
263
+
264
+ function extractUnionsFromType(_schema) {
265
+ while (true) {
266
+ let schema = _schema;
267
+ if (typeof schema !== "object") {
268
+ return [];
269
+ }
270
+ switch (schema._tag) {
271
+ case "Object" :
272
+ return schema._0.flatMap(field => extractUnionsFromType(field.type));
273
+ case "Optional" :
274
+ case "Array" :
275
+ case "Dict" :
276
+ _schema = schema._0;
277
+ continue;
278
+ case "Union" :
279
+ let name = getUnionName(schema._0);
280
+ return [{
281
+ name: name,
282
+ schema: schema
283
+ }];
284
+ default:
285
+ return [];
286
+ }
287
+ };
288
+ }
289
+
290
+ function extractUnions(_parentName, schema) {
291
+ if (typeof schema !== "object") {
292
+ return [];
293
+ } else if (schema._tag === "Object") {
294
+ return schema._0.flatMap(field => extractUnionsFromType(field.type));
295
+ } else {
296
+ return [];
297
+ }
298
+ }
299
+
300
+ function replaceUnionInType(schema) {
301
+ if (typeof schema !== "object") {
302
+ return schema;
303
+ }
304
+ switch (schema._tag) {
305
+ case "Optional" :
306
+ return {
307
+ _tag: "Optional",
308
+ _0: replaceUnionInType(schema._0)
309
+ };
310
+ case "Object" :
311
+ let newFields = schema._0.map(field => {
312
+ let newType = replaceUnionInType(field.type);
313
+ return {
314
+ name: field.name,
315
+ type: newType,
316
+ required: field.required
317
+ };
318
+ });
319
+ return {
320
+ _tag: "Object",
321
+ _0: newFields
322
+ };
323
+ case "Array" :
324
+ return {
325
+ _tag: "Array",
326
+ _0: replaceUnionInType(schema._0)
327
+ };
328
+ case "Dict" :
329
+ return {
330
+ _tag: "Dict",
331
+ _0: replaceUnionInType(schema._0)
332
+ };
333
+ case "Union" :
334
+ return {
335
+ _tag: "Ref",
336
+ _0: getUnionName(schema._0)
337
+ };
338
+ default:
339
+ return schema;
340
+ }
341
+ }
342
+
343
+ function replaceUnions(_parentName, schema) {
344
+ if (typeof schema !== "object") {
345
+ return schema;
346
+ }
347
+ if (schema._tag !== "Object") {
348
+ return schema;
349
+ }
350
+ let newFields = schema._0.map(field => {
351
+ let newType = replaceUnionInType(field.type);
352
+ return {
353
+ name: field.name,
354
+ type: newType,
355
+ required: field.required
356
+ };
357
+ });
358
+ return {
359
+ _tag: "Object",
360
+ _0: newFields
361
+ };
362
+ }
363
+
364
+ function getDependencies(_schema) {
365
+ while (true) {
366
+ let schema = _schema;
367
+ if (typeof schema !== "object") {
368
+ return [];
369
+ }
370
+ switch (schema._tag) {
371
+ case "Object" :
372
+ return schema._0.flatMap(f => getDependencies(f.type));
373
+ case "Ref" :
374
+ return [schema._0];
375
+ case "Enum" :
376
+ return [];
377
+ case "PolyVariant" :
378
+ return schema._0.flatMap(c => getDependencies(c.payload));
379
+ case "Optional" :
380
+ case "Array" :
381
+ case "Dict" :
382
+ _schema = schema._0;
383
+ continue;
384
+ case "Union" :
385
+ return schema._0.flatMap(getDependencies);
386
+ }
387
+ };
388
+ }
389
+
390
+ function topologicalSort(schemas) {
391
+ let schemaMap = {};
392
+ schemas.forEach(s => {
393
+ schemaMap[s.name] = s;
394
+ });
395
+ let deps = {};
396
+ schemas.forEach(s => {
397
+ let refNames = getDependencies(s.schema);
398
+ let validRefs = refNames.filter(name => Core__Option.isSome(schemaMap[name]));
399
+ deps[s.name] = validRefs;
400
+ });
401
+ let outDegree = {};
402
+ schemas.forEach(s => {
403
+ let myDeps = Core__Option.getOr(deps[s.name], []);
404
+ outDegree[s.name] = myDeps.length;
405
+ });
406
+ let reverseDeps = {};
407
+ schemas.forEach(s => {
408
+ reverseDeps[s.name] = [];
409
+ });
410
+ Object.entries(deps).forEach(param => {
411
+ let name = param[0];
412
+ param[1].forEach(refName => {
413
+ let arr = reverseDeps[refName];
414
+ if (arr !== undefined) {
415
+ arr.push(name);
416
+ return;
417
+ }
418
+ });
419
+ });
420
+ let queue = schemas.filter(s => Core__Option.getOr(outDegree[s.name], 0) === 0).map(s => s.name);
421
+ let result = [];
422
+ let visited = {};
423
+ let process = () => {
424
+ while (true) {
425
+ let name = queue.shift();
426
+ if (name === undefined) {
427
+ return;
428
+ }
429
+ if (Core__Option.isNone(visited[name])) {
430
+ visited[name] = true;
431
+ let schema = schemaMap[name];
432
+ if (schema !== undefined) {
433
+ result.push(schema);
434
+ }
435
+ let dependents = reverseDeps[name];
436
+ if (dependents !== undefined) {
437
+ dependents.forEach(depName => {
438
+ let current = Core__Option.getOr(outDegree[depName], 0);
439
+ outDegree[depName] = current - 1 | 0;
440
+ if ((current - 1 | 0) === 0) {
441
+ queue.push(depName);
442
+ return;
443
+ }
444
+ });
445
+ }
446
+ }
447
+ continue;
448
+ };
449
+ };
450
+ process();
451
+ schemas.forEach(s => {
452
+ if (Core__Option.isNone(visited[s.name])) {
453
+ result.push(s);
454
+ return;
455
+ }
456
+ });
457
+ return result;
458
+ }
459
+
460
+ function buildSkipSchemaSet(schemas) {
461
+ let skipSet = {};
462
+ schemas.forEach(s => {
463
+ if (hasUnion(s.schema)) {
464
+ skipSet[s.name] = true;
465
+ return;
466
+ }
467
+ });
468
+ let changed = {
469
+ contents: true
470
+ };
471
+ while (changed.contents) {
472
+ changed.contents = false;
473
+ schemas.forEach(s => {
474
+ if (!Core__Option.isNone(skipSet[s.name])) {
475
+ return;
476
+ }
477
+ let refs = getDependencies(s.schema);
478
+ let refsSkipSchema = refs.some(refName => Core__Option.isSome(skipSet[refName]));
479
+ if (refsSkipSchema) {
480
+ skipSet[s.name] = true;
481
+ changed.contents = true;
482
+ return;
483
+ }
484
+ });
485
+ };
486
+ return skipSet;
487
+ }
488
+
489
+ function generateVariantBody(types) {
490
+ return types.map(t => {
491
+ let tag = getTagForType(t);
492
+ let payload = generateType(t);
493
+ return tag + `(` + payload + `)`;
494
+ }).join(" | ");
495
+ }
496
+
497
+ function generateTypeDefWithSkipSet(namedSchema, _skipSet) {
498
+ let typeName = lcFirst(namedSchema.name);
499
+ let types = namedSchema.schema;
500
+ if (typeof types === "object" && types._tag === "Union") {
501
+ let variantBody = generateVariantBody(types._0);
502
+ return `@genType
503
+ @tag("_tag")
504
+ @schema
505
+ type ` + typeName + ` = ` + variantBody;
506
+ }
507
+ let typeBody = generateType(namedSchema.schema);
508
+ return `@genType
509
+ @schema
510
+ type ` + typeName + ` = ` + typeBody;
511
+ }
512
+
513
+ function generateTypeDef(namedSchema) {
514
+ let typeName = lcFirst(namedSchema.name);
515
+ let types = namedSchema.schema;
516
+ if (typeof types === "object" && types._tag === "Union") {
517
+ let variantBody = generateVariantBody(types._0);
518
+ return `@genType
519
+ @tag("_tag")
520
+ @schema
521
+ type ` + typeName + ` = ` + variantBody;
522
+ }
523
+ let annotations = hasUnion(namedSchema.schema) ? "@genType" : "@genType\n@schema";
524
+ let typeBody = generateType(namedSchema.schema);
525
+ return annotations + `
526
+ type ` + typeName + ` = ` + typeBody;
527
+ }
528
+
529
+ function generateModule(schemas) {
530
+ let extractedUnions = schemas.flatMap(s => extractUnions(s.name, s.schema).map(extracted => ({
531
+ name: extracted.name,
532
+ schema: extracted.schema
533
+ })));
534
+ let seen = {};
535
+ let uniqueUnions = extractedUnions.filter(u => {
536
+ if (Core__Option.isSome(seen[u.name])) {
537
+ return false;
538
+ } else {
539
+ seen[u.name] = true;
540
+ return true;
541
+ }
542
+ });
543
+ let modifiedSchemas = schemas.map(s => ({
544
+ name: s.name,
545
+ schema: replaceUnions(s.name, s.schema)
546
+ }));
547
+ let allSchemas = uniqueUnions.concat(modifiedSchemas);
548
+ let sorted = topologicalSort(allSchemas);
549
+ let skipSet = {};
550
+ return sorted.map(s => generateTypeDefWithSkipSet(s, skipSet)).join("\n\n");
551
+ }
552
+
553
+ export {
554
+ reservedKeywords,
555
+ isReservedKeyword,
556
+ lcFirst,
557
+ generateType,
558
+ isOptionalType,
559
+ generateRecord,
560
+ generatePolyVariant,
561
+ ucFirst,
562
+ getTagForType,
563
+ generateUnion,
564
+ hasUnion,
565
+ getUnionName,
566
+ extractUnions,
567
+ extractUnionsFromType,
568
+ replaceUnions,
569
+ replaceUnionInType,
570
+ getDependencies,
571
+ topologicalSort,
572
+ buildSkipSchemaSet,
573
+ generateVariantBody,
574
+ generateTypeDefWithSkipSet,
575
+ generateTypeDef,
576
+ generateModule,
577
+ }
578
+ /* No side effect */
@@ -0,0 +1,103 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
4
+
5
+ function makeLocation(pathOpt, lineOpt, columnOpt, param) {
6
+ let path = pathOpt !== undefined ? pathOpt : [];
7
+ let line = lineOpt !== undefined ? Primitive_option.valFromOption(lineOpt) : undefined;
8
+ let column = columnOpt !== undefined ? Primitive_option.valFromOption(columnOpt) : undefined;
9
+ return {
10
+ path: path,
11
+ line: line,
12
+ column: column
13
+ };
14
+ }
15
+
16
+ function makeError(kind, pathOpt, hintOpt, param) {
17
+ let path = pathOpt !== undefined ? pathOpt : [];
18
+ let hint = hintOpt !== undefined ? Primitive_option.valFromOption(hintOpt) : undefined;
19
+ return {
20
+ kind: kind,
21
+ location: makeLocation(path, undefined, undefined, undefined),
22
+ hint: hint
23
+ };
24
+ }
25
+
26
+ function unknownType(value, pathOpt, hintOpt, param) {
27
+ let path = pathOpt !== undefined ? pathOpt : [];
28
+ let hint = hintOpt !== undefined ? Primitive_option.valFromOption(hintOpt) : undefined;
29
+ return makeError({
30
+ TAG: "UnknownType",
31
+ _0: value
32
+ }, path, Primitive_option.some(hint), undefined);
33
+ }
34
+
35
+ function missingField(field, pathOpt, hintOpt, param) {
36
+ let path = pathOpt !== undefined ? pathOpt : [];
37
+ let hint = hintOpt !== undefined ? Primitive_option.valFromOption(hintOpt) : undefined;
38
+ return makeError({
39
+ TAG: "MissingRequiredField",
40
+ _0: field
41
+ }, path, Primitive_option.some(hint), undefined);
42
+ }
43
+
44
+ function invalidRef(ref, pathOpt, hintOpt, param) {
45
+ let path = pathOpt !== undefined ? pathOpt : [];
46
+ let hint = hintOpt !== undefined ? Primitive_option.valFromOption(hintOpt) : undefined;
47
+ return makeError({
48
+ TAG: "InvalidRef",
49
+ _0: ref
50
+ }, path, Primitive_option.some(hint), undefined);
51
+ }
52
+
53
+ function formatError(error) {
54
+ let parts = error.location.path;
55
+ let pathStr = parts.length !== 0 ? "#/" + parts.join("/") : "#";
56
+ let value = error.kind;
57
+ let kindStr;
58
+ if (typeof value !== "object") {
59
+ kindStr = "Ambiguous union (anyOf/oneOf cannot be distinguished)";
60
+ } else {
61
+ switch (value.TAG) {
62
+ case "UnknownType" :
63
+ kindStr = `Unknown type "` + value._0 + `"`;
64
+ break;
65
+ case "MissingRequiredField" :
66
+ kindStr = `Missing required field "` + value._0 + `"`;
67
+ break;
68
+ case "InvalidRef" :
69
+ kindStr = `Invalid reference "` + value._0 + `"`;
70
+ break;
71
+ case "UnsupportedFeature" :
72
+ kindStr = `Unsupported feature "` + value._0 + `"`;
73
+ break;
74
+ case "InvalidFormat" :
75
+ kindStr = `Invalid format "` + value._0 + `"`;
76
+ break;
77
+ case "CircularReference" :
78
+ kindStr = `Circular reference detected: "` + value._0 + `"`;
79
+ break;
80
+ case "InvalidJson" :
81
+ kindStr = `Invalid JSON: ` + value._0;
82
+ break;
83
+ }
84
+ }
85
+ let hint = error.hint;
86
+ let hintStr = hint !== undefined ? `\n Hint: ` + hint : "";
87
+ return `Error at ` + pathStr + `:\n ` + kindStr + hintStr;
88
+ }
89
+
90
+ function formatErrors(errors) {
91
+ return errors.map(formatError).join("\n\n");
92
+ }
93
+
94
+ export {
95
+ makeLocation,
96
+ makeError,
97
+ unknownType,
98
+ missingField,
99
+ invalidRef,
100
+ formatError,
101
+ formatErrors,
102
+ }
103
+ /* No side effect */