osury 0.17.3 → 0.19.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/bin/osury.mjs +189 -9
- package/package.json +8 -1
- package/src/BackendReScript.res.mjs +144 -0
- package/src/Codegen.res.mjs +30 -41
- package/src/CodegenHelpers.res.mjs +26 -0
- package/src/CodegenTransforms.res.mjs +93 -1
- package/src/CodegenTypes.res.mjs +36 -14
- package/src/DomainBackend.res.mjs +41 -0
- package/src/DomainConfig.res.mjs +206 -0
- package/src/DomainGen.res.mjs +53 -0
- package/src/DomainIR.res.mjs +2 -0
- package/src/Errors.res.mjs +3 -0
- package/src/IR.res.mjs +2 -0
- package/src/IRGen.res.mjs +352 -0
- package/src/OpenAPIParser.res.mjs +92 -2
- package/src/Schema.res.mjs +219 -158
package/src/CodegenTypes.res.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Core__Option from "@rescript/core/src/Core__Option.res.mjs";
|
|
3
4
|
import * as CodegenHelpers from "./CodegenHelpers.res.mjs";
|
|
4
5
|
|
|
5
6
|
function generateType(schema) {
|
|
@@ -15,6 +16,8 @@ function generateType(schema) {
|
|
|
15
16
|
return "bool";
|
|
16
17
|
case "Null" :
|
|
17
18
|
return "unit";
|
|
19
|
+
case "Unknown" :
|
|
20
|
+
return "JSON.t";
|
|
18
21
|
}
|
|
19
22
|
} else {
|
|
20
23
|
switch (schema._tag) {
|
|
@@ -111,22 +114,40 @@ function generateVariantBody(types) {
|
|
|
111
114
|
|
|
112
115
|
function generateTypeDefWithSkipSet(namedSchema, _skipSet, schemasDict, tagsDict) {
|
|
113
116
|
let typeName = CodegenHelpers.lcFirst(namedSchema.name);
|
|
114
|
-
let
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
let tagName = Core__Option.getOr(namedSchema.discriminatorPropertyName, "_tag");
|
|
118
|
+
let cases = namedSchema.schema;
|
|
119
|
+
if (typeof cases === "object") {
|
|
120
|
+
switch (cases._tag) {
|
|
121
|
+
case "PolyVariant" :
|
|
122
|
+
let variantBody = cases._0.map(c => {
|
|
123
|
+
let refName = c.payload;
|
|
124
|
+
if (typeof refName === "object" && refName._tag === "Ref") {
|
|
125
|
+
let inlineRecord = generateInlineRecord(refName._0, schemasDict);
|
|
126
|
+
return CodegenHelpers.ucFirst(c._tag) + `(` + inlineRecord + `)`;
|
|
127
|
+
}
|
|
128
|
+
let payloadStr = generateType(c.payload);
|
|
129
|
+
return CodegenHelpers.ucFirst(c._tag) + `(` + payloadStr + `)`;
|
|
130
|
+
}).join(" | ");
|
|
131
|
+
return `@genType
|
|
132
|
+
@tag("` + tagName + `")
|
|
122
133
|
@schema
|
|
123
134
|
type ` + typeName + ` = ` + variantBody;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
case "Union" :
|
|
136
|
+
let types = cases._0;
|
|
137
|
+
if (CodegenHelpers.isPrimitiveOnlyUnion(types)) {
|
|
138
|
+
let variantBody$1 = generateVariantBody(types);
|
|
139
|
+
return `@genType
|
|
140
|
+
@tag("` + tagName + `")
|
|
141
|
+
@unboxed
|
|
128
142
|
@schema
|
|
129
143
|
type ` + typeName + ` = ` + variantBody$1;
|
|
144
|
+
}
|
|
145
|
+
let variantBody$2 = generateInlineVariantBody(types, schemasDict, tagsDict);
|
|
146
|
+
return `@genType
|
|
147
|
+
@tag("` + tagName + `")
|
|
148
|
+
@schema
|
|
149
|
+
type ` + typeName + ` = ` + variantBody$2;
|
|
150
|
+
}
|
|
130
151
|
}
|
|
131
152
|
let typeBody = generateType(namedSchema.schema);
|
|
132
153
|
return `@genType
|
|
@@ -136,16 +157,17 @@ type ` + typeName + ` = ` + typeBody;
|
|
|
136
157
|
|
|
137
158
|
function generateTypeDef(namedSchema) {
|
|
138
159
|
let typeName = CodegenHelpers.lcFirst(namedSchema.name);
|
|
160
|
+
let tagName = Core__Option.getOr(namedSchema.discriminatorPropertyName, "_tag");
|
|
139
161
|
let types = namedSchema.schema;
|
|
140
162
|
if (typeof types === "object" && types._tag === "Union") {
|
|
141
163
|
let variantBody = generateVariantBody(types._0);
|
|
142
164
|
return `@genType
|
|
143
|
-
@tag("
|
|
165
|
+
@tag("` + tagName + `")
|
|
144
166
|
@unboxed
|
|
145
167
|
@schema
|
|
146
168
|
type ` + typeName + ` = ` + variantBody;
|
|
147
169
|
}
|
|
148
|
-
let annotations = CodegenHelpers.hasUnion(namedSchema.schema) ? "@genType" : "@genType\n@schema";
|
|
170
|
+
let annotations = CodegenHelpers.hasUnion(namedSchema.schema) || CodegenHelpers.hasUnknown(namedSchema.schema) ? "@genType" : "@genType\n@schema";
|
|
149
171
|
let typeBody = generateType(namedSchema.schema);
|
|
150
172
|
return annotations + `
|
|
151
173
|
type ` + typeName + ` = ` + typeBody;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function printField(field) {
|
|
5
|
+
return ` ` + field.name + `: ` + field.typeAnnotation + `,`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function printType(module_) {
|
|
9
|
+
let fields = module_.fields.map(printField).join("\n");
|
|
10
|
+
return `type t = {\n` + fields + `\n}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function printMakeField(field) {
|
|
14
|
+
let fn = field.mapping;
|
|
15
|
+
if (fn.TAG === "Mapper") {
|
|
16
|
+
return ` ` + field.name + `: ` + fn._0 + `(raw),`;
|
|
17
|
+
} else {
|
|
18
|
+
return ` ` + field.name + `: raw.` + fn._0 + `,`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function printMake(module_) {
|
|
23
|
+
let fields = module_.fields.map(printMakeField).join("\n");
|
|
24
|
+
return `let make = (raw: ` + module_.sourceType + `): t => {\n` + fields + `\n}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function printModule(module_) {
|
|
28
|
+
let header = `// ` + module_.output + ` (generated by osury — do not edit)`;
|
|
29
|
+
let typeBlock = printType(module_);
|
|
30
|
+
let makeBlock = printMake(module_);
|
|
31
|
+
return header + "\n\n" + typeBlock + "\n\n" + makeBlock + "\n";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {
|
|
35
|
+
printField,
|
|
36
|
+
printType,
|
|
37
|
+
printMakeField,
|
|
38
|
+
printMake,
|
|
39
|
+
printModule,
|
|
40
|
+
}
|
|
41
|
+
/* No side effect */
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Errors from "./Errors.res.mjs";
|
|
4
|
+
import * as Core__Array from "@rescript/core/src/Core__Array.res.mjs";
|
|
5
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
|
+
|
|
7
|
+
function parseFieldConfig(name, json) {
|
|
8
|
+
if (typeof json === "object" && json !== null && !Array.isArray(json)) {
|
|
9
|
+
let match = json["type"];
|
|
10
|
+
let exit = 0;
|
|
11
|
+
if (match !== undefined) {
|
|
12
|
+
if (typeof match === "string") {
|
|
13
|
+
let match$1 = json["mapper"];
|
|
14
|
+
let mapper = typeof match$1 === "string" ? match$1 : undefined;
|
|
15
|
+
let match$2 = json["source"];
|
|
16
|
+
let source = typeof match$2 === "string" ? match$2 : undefined;
|
|
17
|
+
return {
|
|
18
|
+
TAG: "Ok",
|
|
19
|
+
_0: [
|
|
20
|
+
name,
|
|
21
|
+
{
|
|
22
|
+
type_: match,
|
|
23
|
+
mapper: mapper,
|
|
24
|
+
source: source
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
exit = 2;
|
|
30
|
+
} else {
|
|
31
|
+
exit = 2;
|
|
32
|
+
}
|
|
33
|
+
if (exit === 2) {
|
|
34
|
+
return {
|
|
35
|
+
TAG: "Error",
|
|
36
|
+
_0: [Errors.makeError({
|
|
37
|
+
TAG: "MissingRequiredField",
|
|
38
|
+
_0: "type"
|
|
39
|
+
}, [
|
|
40
|
+
"fields",
|
|
41
|
+
name
|
|
42
|
+
], Primitive_option.some(`Field "` + name + `" must have a "type" property`), undefined)]
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
TAG: "Error",
|
|
48
|
+
_0: [Errors.makeError({
|
|
49
|
+
TAG: "InvalidJson",
|
|
50
|
+
_0: `field "` + name + `" must be an object`
|
|
51
|
+
}, [
|
|
52
|
+
"fields",
|
|
53
|
+
name
|
|
54
|
+
], undefined, undefined)]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseModuleConfig(name, json) {
|
|
59
|
+
if (typeof json === "object" && json !== null && !Array.isArray(json)) {
|
|
60
|
+
let match = json["source"];
|
|
61
|
+
let exit = 0;
|
|
62
|
+
if (typeof match === "string") {
|
|
63
|
+
let match$1 = json["output"];
|
|
64
|
+
let output = typeof match$1 === "string" ? match$1 : undefined;
|
|
65
|
+
let match$2 = json["fields"];
|
|
66
|
+
let exit$1 = 0;
|
|
67
|
+
if (match$2 !== undefined) {
|
|
68
|
+
if (typeof match$2 === "object" && match$2 !== null && !Array.isArray(match$2)) {
|
|
69
|
+
let entries = Object.entries(match$2);
|
|
70
|
+
let results = entries.map(param => parseFieldConfig(param[0], param[1]));
|
|
71
|
+
let errors = Core__Array.filterMap(results, r => {
|
|
72
|
+
if (r.TAG === "Ok") {
|
|
73
|
+
return;
|
|
74
|
+
} else {
|
|
75
|
+
return r._0;
|
|
76
|
+
}
|
|
77
|
+
}).flat();
|
|
78
|
+
if (errors.length > 0) {
|
|
79
|
+
return {
|
|
80
|
+
TAG: "Error",
|
|
81
|
+
_0: errors
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
let fields = Core__Array.filterMap(results, r => {
|
|
85
|
+
if (r.TAG === "Ok") {
|
|
86
|
+
return r._0;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
TAG: "Ok",
|
|
91
|
+
_0: [
|
|
92
|
+
name,
|
|
93
|
+
{
|
|
94
|
+
source: match,
|
|
95
|
+
output: output,
|
|
96
|
+
fields: fields
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
exit$1 = 3;
|
|
102
|
+
} else {
|
|
103
|
+
exit$1 = 3;
|
|
104
|
+
}
|
|
105
|
+
if (exit$1 === 3) {
|
|
106
|
+
return {
|
|
107
|
+
TAG: "Error",
|
|
108
|
+
_0: [Errors.makeError({
|
|
109
|
+
TAG: "MissingRequiredField",
|
|
110
|
+
_0: "fields"
|
|
111
|
+
}, [
|
|
112
|
+
"modules",
|
|
113
|
+
name
|
|
114
|
+
], Primitive_option.some(`Module "` + name + `" must have a "fields" object`), undefined)]
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
exit = 2;
|
|
119
|
+
}
|
|
120
|
+
if (exit === 2) {
|
|
121
|
+
return {
|
|
122
|
+
TAG: "Error",
|
|
123
|
+
_0: [Errors.makeError({
|
|
124
|
+
TAG: "MissingRequiredField",
|
|
125
|
+
_0: "source"
|
|
126
|
+
}, [
|
|
127
|
+
"modules",
|
|
128
|
+
name
|
|
129
|
+
], Primitive_option.some(`Module "` + name + `" must have a "source" property referencing the API type`), undefined)]
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
TAG: "Error",
|
|
135
|
+
_0: [Errors.makeError({
|
|
136
|
+
TAG: "InvalidJson",
|
|
137
|
+
_0: `module "` + name + `" must be an object`
|
|
138
|
+
}, [
|
|
139
|
+
"modules",
|
|
140
|
+
name
|
|
141
|
+
], undefined, undefined)]
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function parse(json) {
|
|
146
|
+
if (typeof json === "object" && json !== null && !Array.isArray(json)) {
|
|
147
|
+
let match = json["modules"];
|
|
148
|
+
let exit = 0;
|
|
149
|
+
if (match !== undefined) {
|
|
150
|
+
if (typeof match === "object" && match !== null && !Array.isArray(match)) {
|
|
151
|
+
let entries = Object.entries(match);
|
|
152
|
+
let results = entries.map(param => parseModuleConfig(param[0], param[1]));
|
|
153
|
+
let errors = Core__Array.filterMap(results, r => {
|
|
154
|
+
if (r.TAG === "Ok") {
|
|
155
|
+
return;
|
|
156
|
+
} else {
|
|
157
|
+
return r._0;
|
|
158
|
+
}
|
|
159
|
+
}).flat();
|
|
160
|
+
if (errors.length > 0) {
|
|
161
|
+
return {
|
|
162
|
+
TAG: "Error",
|
|
163
|
+
_0: errors
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
let modules = Core__Array.filterMap(results, r => {
|
|
167
|
+
if (r.TAG === "Ok") {
|
|
168
|
+
return r._0;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
return {
|
|
172
|
+
TAG: "Ok",
|
|
173
|
+
_0: {
|
|
174
|
+
modules: modules
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
exit = 2;
|
|
179
|
+
} else {
|
|
180
|
+
exit = 2;
|
|
181
|
+
}
|
|
182
|
+
if (exit === 2) {
|
|
183
|
+
return {
|
|
184
|
+
TAG: "Error",
|
|
185
|
+
_0: [Errors.makeError({
|
|
186
|
+
TAG: "MissingRequiredField",
|
|
187
|
+
_0: "modules"
|
|
188
|
+
}, [], `Config must have a "modules" object`, undefined)]
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
TAG: "Error",
|
|
194
|
+
_0: [Errors.makeError({
|
|
195
|
+
TAG: "InvalidJson",
|
|
196
|
+
_0: "config must be an object"
|
|
197
|
+
}, undefined, undefined, undefined)]
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export {
|
|
202
|
+
parseFieldConfig,
|
|
203
|
+
parseModuleConfig,
|
|
204
|
+
parse,
|
|
205
|
+
}
|
|
206
|
+
/* No side effect */
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function generateField(param) {
|
|
5
|
+
let fieldConfig = param[1];
|
|
6
|
+
let name = param[0];
|
|
7
|
+
let mapper = fieldConfig.mapper;
|
|
8
|
+
let mapping;
|
|
9
|
+
if (mapper !== undefined) {
|
|
10
|
+
mapping = {
|
|
11
|
+
TAG: "Mapper",
|
|
12
|
+
_0: mapper
|
|
13
|
+
};
|
|
14
|
+
} else {
|
|
15
|
+
let s = fieldConfig.source;
|
|
16
|
+
let sourceName = s !== undefined ? s : name;
|
|
17
|
+
mapping = {
|
|
18
|
+
TAG: "Passthrough",
|
|
19
|
+
_0: sourceName
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
name: name,
|
|
24
|
+
typeAnnotation: fieldConfig.type_,
|
|
25
|
+
mapping: mapping
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function generateModule(param, apiModule) {
|
|
30
|
+
let moduleConfig = param[1];
|
|
31
|
+
let name = param[0];
|
|
32
|
+
let o = moduleConfig.output;
|
|
33
|
+
let output = o !== undefined ? o : name + ".gen.res";
|
|
34
|
+
let sourceType = apiModule + "." + moduleConfig.source;
|
|
35
|
+
let fields = moduleConfig.fields.map(generateField);
|
|
36
|
+
return {
|
|
37
|
+
name: name,
|
|
38
|
+
sourceType: sourceType,
|
|
39
|
+
output: output,
|
|
40
|
+
fields: fields
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function generate(config, apiModule) {
|
|
45
|
+
return config.modules.map(entry => generateModule(entry, apiModule));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
generateField,
|
|
50
|
+
generateModule,
|
|
51
|
+
generate,
|
|
52
|
+
}
|
|
53
|
+
/* No side effect */
|
package/src/Errors.res.mjs
CHANGED
|
@@ -77,6 +77,9 @@ function formatError(error) {
|
|
|
77
77
|
case "CircularReference" :
|
|
78
78
|
kindStr = `Circular reference detected: "` + value._0 + `"`;
|
|
79
79
|
break;
|
|
80
|
+
case "MissingDiscriminator" :
|
|
81
|
+
kindStr = `Missing discriminator for union "` + value._0 + `"`;
|
|
82
|
+
break;
|
|
80
83
|
case "InvalidJson" :
|
|
81
84
|
kindStr = `Invalid JSON: ` + value._0;
|
|
82
85
|
break;
|
package/src/IR.res.mjs
ADDED