@sdkgen/fsharp-generator 0.0.0-dev.20231008160426 → 0.0.0-dev.20231221180829
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/.eslintrc.json +3 -0
- package/.prettierrc +12 -0
- package/dist/src/fsharp-server.js +93 -0
- package/dist/src/helpers.js +497 -0
- package/dist/src/index.js +17 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +11 -27
- package/dist/fsharp-server.js +0 -90
- package/dist/helpers.js +0 -488
- package/dist/index.js +0 -2
- /package/dist/{fsharp-server.d.ts → src/fsharp-server.d.ts} +0 -0
- /package/dist/{helpers.d.ts → src/helpers.d.ts} +0 -0
- /package/dist/{index.d.ts → src/index.d.ts} +0 -0
package/.eslintrc.json
ADDED
package/.prettierrc
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateFSharpServerSource = void 0;
|
|
4
|
+
const parser_1 = require("@sdkgen/parser");
|
|
5
|
+
const helpers_1 = require("./helpers");
|
|
6
|
+
function generateFSharpServerSource(ast) {
|
|
7
|
+
let code = `module rec SdkgenGenerated
|
|
8
|
+
open Sdkgen.Runtime
|
|
9
|
+
open Sdkgen.Helpers
|
|
10
|
+
open Sdkgen.Context
|
|
11
|
+
open System.Threading.Tasks
|
|
12
|
+
open System.Text.Json
|
|
13
|
+
open System
|
|
14
|
+
open System.Globalization
|
|
15
|
+
#if NET5_0
|
|
16
|
+
// To use tasks as computation expression in .NET 5 install https://www.nuget.org/packages/TaskBuilder.fs/
|
|
17
|
+
open FSharp.Control.Tasks.V2.ContextInsensitive
|
|
18
|
+
#endif
|
|
19
|
+
`;
|
|
20
|
+
for (const error of ast.errors) {
|
|
21
|
+
code += `
|
|
22
|
+
type ${error.name}Exception =
|
|
23
|
+
inherit SdkgenException
|
|
24
|
+
|
|
25
|
+
new(message: string) = {
|
|
26
|
+
inherit SdkgenException("${error.name}", message, null)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
new(message: string, inner: Exception) = {
|
|
30
|
+
inherit SdkgenException("${error.name}", message, inner)
|
|
31
|
+
}\n`;
|
|
32
|
+
}
|
|
33
|
+
for (const type of ast.enumTypes) {
|
|
34
|
+
code += `\n${(0, helpers_1.generateEnum)(type)}\n`;
|
|
35
|
+
}
|
|
36
|
+
for (const type of ast.structTypes) {
|
|
37
|
+
code += `\n${(0, helpers_1.generateStruct)(type)}\n`;
|
|
38
|
+
}
|
|
39
|
+
code += `
|
|
40
|
+
type Api() =`;
|
|
41
|
+
for (const op of ast.operations) {
|
|
42
|
+
const returnTypeAngle = op.returnType instanceof parser_1.VoidPrimitiveType ? "" : `<${(0, helpers_1.generateTypeName)(op.returnType)}>`;
|
|
43
|
+
const argsInRecord = op.args.length > 0 ? `{| ${op.args.map(arg => `${arg.name}: ${(0, helpers_1.generateTypeName)(arg.type)};`).join("")} |} ->` : "";
|
|
44
|
+
code += `
|
|
45
|
+
member val ${(0, helpers_1.capitalize)(op.name)}: Context -> ${argsInRecord} Task${returnTypeAngle} =
|
|
46
|
+
fun _ -> (raise (FatalException("Function '${op.name}' not implemented.")))
|
|
47
|
+
with get, set
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
code += `
|
|
51
|
+
interface BaseApi with
|
|
52
|
+
member __.ExecuteFunction(context_: Context, resultWriter_: Utf8JsonWriter) : Task =
|
|
53
|
+
task {
|
|
54
|
+
match context_.Name with`;
|
|
55
|
+
for (const op of ast.operations) {
|
|
56
|
+
code += `
|
|
57
|
+
| ${JSON.stringify(op.name)} ->`;
|
|
58
|
+
for (const arg of op.args) {
|
|
59
|
+
code += `
|
|
60
|
+
let ${arg.name}Json_ =
|
|
61
|
+
match context_.Args.TryGetValue(${JSON.stringify(arg.name)}) with
|
|
62
|
+
| true, v -> v
|
|
63
|
+
| _ -> raise (FatalException("'${op.name}().args.${arg.name}' must be set to a value of type ${arg.type.name}."))
|
|
64
|
+
|
|
65
|
+
let ${(0, helpers_1.ident)(arg.name)} =
|
|
66
|
+
${(0, helpers_1.decodeType)(arg.type, `${arg.name}Json_`, `"${op.name}().args.${arg.name}"`, (0, helpers_1.ident)(arg.name)).replace(/\n/gu, "\n ")}`;
|
|
67
|
+
}
|
|
68
|
+
if (op.returnType instanceof parser_1.VoidPrimitiveType) {
|
|
69
|
+
code += `
|
|
70
|
+
|
|
71
|
+
do! (__.${(0, helpers_1.capitalize)(op.name)} context_ ${op.args.length > 0 ? "{|" : ""} ${op.args
|
|
72
|
+
.map(arg => `${arg.name} = ${(0, helpers_1.ident)(arg.name)}`)
|
|
73
|
+
.join("; ")} ${op.args.length > 0 ? "|}" : ""})
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
code += `
|
|
78
|
+
|
|
79
|
+
let! result_ = (__.${(0, helpers_1.capitalize)(op.name)} context_ ${op.args.length > 0 ? "{|" : ""} ${op.args
|
|
80
|
+
.map(arg => `${arg.name} = ${(0, helpers_1.ident)(arg.name)}`)
|
|
81
|
+
.join("; ")} ${op.args.length > 0 ? "|}" : ""})
|
|
82
|
+
${(0, helpers_1.encodeType)(op.returnType, `result_`, `"${op.name}().ret"`, 1, false).replace(/\n/gu, "\n ")}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
code += `
|
|
86
|
+
|
|
87
|
+
| _ -> raise (FatalException($"Unknown function '{context_.Name}'."))
|
|
88
|
+
} :> Task`;
|
|
89
|
+
code += `
|
|
90
|
+
member __.GetAstJson() = """${JSON.stringify((0, parser_1.astToJson)(ast), null, 4).replace(/\n/gu, "\n ")}""";`;
|
|
91
|
+
return code;
|
|
92
|
+
}
|
|
93
|
+
exports.generateFSharpServerSource = generateFSharpServerSource;
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateEnum = exports.generateStruct = exports.encodeType = exports.decodeType = exports.generateTypeName = exports.capitalize = exports.ident = void 0;
|
|
4
|
+
const parser_1 = require("@sdkgen/parser");
|
|
5
|
+
const reservedWords = [
|
|
6
|
+
"abstract",
|
|
7
|
+
"as",
|
|
8
|
+
"base",
|
|
9
|
+
"bool",
|
|
10
|
+
"break",
|
|
11
|
+
"byte",
|
|
12
|
+
"case",
|
|
13
|
+
"catch",
|
|
14
|
+
"char",
|
|
15
|
+
"checked",
|
|
16
|
+
"class",
|
|
17
|
+
"const",
|
|
18
|
+
"continue",
|
|
19
|
+
"decimal",
|
|
20
|
+
"default",
|
|
21
|
+
"delegate",
|
|
22
|
+
"do",
|
|
23
|
+
"double",
|
|
24
|
+
"else",
|
|
25
|
+
"enum",
|
|
26
|
+
"event",
|
|
27
|
+
"explicit",
|
|
28
|
+
"extern",
|
|
29
|
+
"false",
|
|
30
|
+
"finally",
|
|
31
|
+
"fixed",
|
|
32
|
+
"float",
|
|
33
|
+
"for",
|
|
34
|
+
"foreach",
|
|
35
|
+
"goto",
|
|
36
|
+
"if",
|
|
37
|
+
"implicit",
|
|
38
|
+
"in",
|
|
39
|
+
"int",
|
|
40
|
+
"interface",
|
|
41
|
+
"internal",
|
|
42
|
+
"is",
|
|
43
|
+
"lock",
|
|
44
|
+
"long",
|
|
45
|
+
"namespace",
|
|
46
|
+
"new",
|
|
47
|
+
"null",
|
|
48
|
+
"object",
|
|
49
|
+
"operator",
|
|
50
|
+
"out",
|
|
51
|
+
"override",
|
|
52
|
+
"params",
|
|
53
|
+
"private",
|
|
54
|
+
"protected",
|
|
55
|
+
"public",
|
|
56
|
+
"readonly",
|
|
57
|
+
"ref",
|
|
58
|
+
"return",
|
|
59
|
+
"sbyte",
|
|
60
|
+
"sealed",
|
|
61
|
+
"short",
|
|
62
|
+
"sizeof",
|
|
63
|
+
"stackalloc",
|
|
64
|
+
"static",
|
|
65
|
+
"string",
|
|
66
|
+
"struct",
|
|
67
|
+
"switch",
|
|
68
|
+
"this",
|
|
69
|
+
"throw",
|
|
70
|
+
"true",
|
|
71
|
+
"try",
|
|
72
|
+
"typeof",
|
|
73
|
+
"uint",
|
|
74
|
+
"ulong",
|
|
75
|
+
"unchecked",
|
|
76
|
+
"unsafe",
|
|
77
|
+
"ushort",
|
|
78
|
+
"using",
|
|
79
|
+
"using",
|
|
80
|
+
"static",
|
|
81
|
+
"virtual",
|
|
82
|
+
"void",
|
|
83
|
+
"volatile",
|
|
84
|
+
"while",
|
|
85
|
+
"type",
|
|
86
|
+
"end",
|
|
87
|
+
"id",
|
|
88
|
+
];
|
|
89
|
+
const typesWithNativeNullable = [
|
|
90
|
+
parser_1.StringPrimitiveType,
|
|
91
|
+
parser_1.HtmlPrimitiveType,
|
|
92
|
+
parser_1.CpfPrimitiveType,
|
|
93
|
+
parser_1.CnpjPrimitiveType,
|
|
94
|
+
parser_1.BytesPrimitiveType,
|
|
95
|
+
parser_1.EmailPrimitiveType,
|
|
96
|
+
parser_1.UrlPrimitiveType,
|
|
97
|
+
parser_1.UuidPrimitiveType,
|
|
98
|
+
parser_1.HexPrimitiveType,
|
|
99
|
+
parser_1.Base64PrimitiveType,
|
|
100
|
+
parser_1.XmlPrimitiveType,
|
|
101
|
+
parser_1.StructType,
|
|
102
|
+
parser_1.ArrayType,
|
|
103
|
+
];
|
|
104
|
+
const needsTempVarForNullable = [
|
|
105
|
+
parser_1.BigIntPrimitiveType,
|
|
106
|
+
parser_1.DatePrimitiveType,
|
|
107
|
+
parser_1.DateTimePrimitiveType,
|
|
108
|
+
parser_1.FloatPrimitiveType,
|
|
109
|
+
parser_1.IntPrimitiveType,
|
|
110
|
+
parser_1.MoneyPrimitiveType,
|
|
111
|
+
parser_1.UIntPrimitiveType,
|
|
112
|
+
parser_1.ArrayType,
|
|
113
|
+
];
|
|
114
|
+
function ident(name) {
|
|
115
|
+
return reservedWords.includes(name) ? `${name}'` : name;
|
|
116
|
+
}
|
|
117
|
+
exports.ident = ident;
|
|
118
|
+
function capitalize(name) {
|
|
119
|
+
return name[0].toUpperCase() + name.slice(1);
|
|
120
|
+
}
|
|
121
|
+
exports.capitalize = capitalize;
|
|
122
|
+
function generateTypeName(type) {
|
|
123
|
+
switch (type.constructor) {
|
|
124
|
+
case parser_1.StringPrimitiveType:
|
|
125
|
+
return "string";
|
|
126
|
+
case parser_1.IntPrimitiveType:
|
|
127
|
+
return "int";
|
|
128
|
+
case parser_1.UIntPrimitiveType:
|
|
129
|
+
return "uint";
|
|
130
|
+
case parser_1.FloatPrimitiveType:
|
|
131
|
+
return "double";
|
|
132
|
+
case parser_1.BigIntPrimitiveType:
|
|
133
|
+
return "bigint";
|
|
134
|
+
case parser_1.DatePrimitiveType:
|
|
135
|
+
case parser_1.DateTimePrimitiveType:
|
|
136
|
+
return "DateTime";
|
|
137
|
+
case parser_1.BoolPrimitiveType:
|
|
138
|
+
return "bool";
|
|
139
|
+
case parser_1.BytesPrimitiveType:
|
|
140
|
+
return "byte[]";
|
|
141
|
+
case parser_1.MoneyPrimitiveType:
|
|
142
|
+
return "decimal";
|
|
143
|
+
case parser_1.UuidPrimitiveType:
|
|
144
|
+
return "Guid";
|
|
145
|
+
case parser_1.CpfPrimitiveType:
|
|
146
|
+
case parser_1.CnpjPrimitiveType:
|
|
147
|
+
case parser_1.EmailPrimitiveType:
|
|
148
|
+
case parser_1.HtmlPrimitiveType:
|
|
149
|
+
case parser_1.UrlPrimitiveType:
|
|
150
|
+
case parser_1.HexPrimitiveType:
|
|
151
|
+
case parser_1.Base64PrimitiveType:
|
|
152
|
+
case parser_1.XmlPrimitiveType:
|
|
153
|
+
return "string";
|
|
154
|
+
case parser_1.VoidPrimitiveType:
|
|
155
|
+
return "void";
|
|
156
|
+
case parser_1.JsonPrimitiveType:
|
|
157
|
+
return "JsonElement";
|
|
158
|
+
case parser_1.OptionalType:
|
|
159
|
+
return `${generateTypeName(type.base)} option`;
|
|
160
|
+
case parser_1.ArrayType:
|
|
161
|
+
return `${generateTypeName(type.base)} list`;
|
|
162
|
+
case parser_1.StructType:
|
|
163
|
+
return type.name;
|
|
164
|
+
case parser_1.EnumType:
|
|
165
|
+
return type.name;
|
|
166
|
+
case parser_1.TypeReference:
|
|
167
|
+
return generateTypeName(type.type);
|
|
168
|
+
default:
|
|
169
|
+
throw new Error(`BUG: generateTypeName with ${type.constructor.name}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.generateTypeName = generateTypeName;
|
|
173
|
+
function decodeType(type, jsonElementVar, path, targetVar, suffix = 1, maybeNull = true) {
|
|
174
|
+
switch (type.constructor) {
|
|
175
|
+
case parser_1.IntPrimitiveType: {
|
|
176
|
+
return `
|
|
177
|
+
decodeInt32 ${jsonElementVar} ${path}
|
|
178
|
+
`
|
|
179
|
+
.replace(/\n {16}/gu, "\n")
|
|
180
|
+
.trim();
|
|
181
|
+
}
|
|
182
|
+
case parser_1.UIntPrimitiveType: {
|
|
183
|
+
return `
|
|
184
|
+
decodeUInt32 ${jsonElementVar} ${path}
|
|
185
|
+
`
|
|
186
|
+
.replace(/\n {16}/gu, "\n")
|
|
187
|
+
.trim();
|
|
188
|
+
}
|
|
189
|
+
case parser_1.MoneyPrimitiveType: {
|
|
190
|
+
return `
|
|
191
|
+
(decodeMoney ${jsonElementVar} ${path}) / 100m
|
|
192
|
+
`
|
|
193
|
+
.replace(/\n {16}/gu, "\n")
|
|
194
|
+
.trim();
|
|
195
|
+
}
|
|
196
|
+
case parser_1.FloatPrimitiveType: {
|
|
197
|
+
return `
|
|
198
|
+
decodeFloat ${jsonElementVar} ${path}
|
|
199
|
+
`
|
|
200
|
+
.replace(/\n {16}/gu, "\n")
|
|
201
|
+
.trim();
|
|
202
|
+
}
|
|
203
|
+
case parser_1.BigIntPrimitiveType: {
|
|
204
|
+
return `
|
|
205
|
+
decodeBigInt ${jsonElementVar} ${path}
|
|
206
|
+
`
|
|
207
|
+
.replace(/\n {16}/gu, "\n")
|
|
208
|
+
.trim();
|
|
209
|
+
}
|
|
210
|
+
case parser_1.StringPrimitiveType: {
|
|
211
|
+
return `
|
|
212
|
+
decodeString ${jsonElementVar} ${path}
|
|
213
|
+
`
|
|
214
|
+
.replace(/\n {16}/gu, "\n")
|
|
215
|
+
.trim();
|
|
216
|
+
}
|
|
217
|
+
case parser_1.HtmlPrimitiveType: {
|
|
218
|
+
// TODO: validate HTML
|
|
219
|
+
return `
|
|
220
|
+
decodeHtml ${jsonElementVar} ${path}
|
|
221
|
+
`
|
|
222
|
+
.replace(/\n {16}/gu, "\n")
|
|
223
|
+
.trim();
|
|
224
|
+
}
|
|
225
|
+
case parser_1.CpfPrimitiveType: {
|
|
226
|
+
// TODO: validate CPF
|
|
227
|
+
return `
|
|
228
|
+
decodeCpf ${jsonElementVar} ${path}
|
|
229
|
+
`
|
|
230
|
+
.replace(/\n {16}/gu, "\n")
|
|
231
|
+
.trim();
|
|
232
|
+
}
|
|
233
|
+
case parser_1.CnpjPrimitiveType: {
|
|
234
|
+
// TODO: validate CNPJ
|
|
235
|
+
return `
|
|
236
|
+
decodeCnpj ${jsonElementVar} ${path}
|
|
237
|
+
`
|
|
238
|
+
.replace(/\n {16}/gu, "\n")
|
|
239
|
+
.trim();
|
|
240
|
+
}
|
|
241
|
+
case parser_1.EmailPrimitiveType: {
|
|
242
|
+
// TODO: validate Email
|
|
243
|
+
return `
|
|
244
|
+
decodeEmail ${jsonElementVar} ${path}
|
|
245
|
+
`
|
|
246
|
+
.replace(/\n {16}/gu, "\n")
|
|
247
|
+
.trim();
|
|
248
|
+
}
|
|
249
|
+
case parser_1.UrlPrimitiveType: {
|
|
250
|
+
// TODO: validate URL
|
|
251
|
+
return `
|
|
252
|
+
decodeUrl ${jsonElementVar} ${path}
|
|
253
|
+
`
|
|
254
|
+
.replace(/\n {16}/gu, "\n")
|
|
255
|
+
.trim();
|
|
256
|
+
}
|
|
257
|
+
case parser_1.UuidPrimitiveType: {
|
|
258
|
+
// TODO: validate UUID
|
|
259
|
+
return `
|
|
260
|
+
decodeUuid ${jsonElementVar} ${path}
|
|
261
|
+
`
|
|
262
|
+
.replace(/\n {16}/gu, "\n")
|
|
263
|
+
.trim();
|
|
264
|
+
}
|
|
265
|
+
case parser_1.HexPrimitiveType: {
|
|
266
|
+
// TODO: validate Hex
|
|
267
|
+
return `
|
|
268
|
+
decodeHex ${jsonElementVar} ${path}
|
|
269
|
+
`
|
|
270
|
+
.replace(/\n {16}/gu, "\n")
|
|
271
|
+
.trim();
|
|
272
|
+
}
|
|
273
|
+
case parser_1.Base64PrimitiveType: {
|
|
274
|
+
// TODO: validate Base64
|
|
275
|
+
return `
|
|
276
|
+
decodeBase64 ${jsonElementVar} ${path}
|
|
277
|
+
`
|
|
278
|
+
.replace(/\n {16}/gu, "\n")
|
|
279
|
+
.trim();
|
|
280
|
+
}
|
|
281
|
+
case parser_1.XmlPrimitiveType: {
|
|
282
|
+
// TODO: validate XML
|
|
283
|
+
return `
|
|
284
|
+
decodeXml ${jsonElementVar} ${path}
|
|
285
|
+
`
|
|
286
|
+
.replace(/\n {16}/gu, "\n")
|
|
287
|
+
.trim();
|
|
288
|
+
}
|
|
289
|
+
case parser_1.BoolPrimitiveType: {
|
|
290
|
+
return `
|
|
291
|
+
decodeBool ${jsonElementVar} ${path}
|
|
292
|
+
`
|
|
293
|
+
.replace(/\n {16}/gu, "\n")
|
|
294
|
+
.trim();
|
|
295
|
+
}
|
|
296
|
+
case parser_1.BytesPrimitiveType: {
|
|
297
|
+
return `
|
|
298
|
+
decodeBytes ${jsonElementVar} ${path}
|
|
299
|
+
`
|
|
300
|
+
.replace(/\n {16}/gu, "\n")
|
|
301
|
+
.trim();
|
|
302
|
+
}
|
|
303
|
+
case parser_1.TypeReference:
|
|
304
|
+
return decodeType(type.type, jsonElementVar, path, targetVar, suffix);
|
|
305
|
+
case parser_1.OptionalType:
|
|
306
|
+
if (needsTempVarForNullable.includes(type.base.constructor)) {
|
|
307
|
+
return `match ${jsonElementVar}.ValueKind with
|
|
308
|
+
| JsonValueKind.Null | JsonValueKind.Undefined -> None
|
|
309
|
+
| _ ->
|
|
310
|
+
(${decodeType(type.base, jsonElementVar, path, targetVar, suffix, false).replace(/\n/gu, "\n ")}) |> Some
|
|
311
|
+
`
|
|
312
|
+
.replace(/\n {16}/gu, "\n")
|
|
313
|
+
.trim();
|
|
314
|
+
}
|
|
315
|
+
if (type.base instanceof parser_1.OptionalType || type.base instanceof parser_1.ArrayType) {
|
|
316
|
+
return `
|
|
317
|
+
(>.>) decodeOptional ${decodeType(type.base, jsonElementVar, path, targetVar, suffix, false)}
|
|
318
|
+
`
|
|
319
|
+
.replace(/\n {16}/gu, "\n")
|
|
320
|
+
.trim();
|
|
321
|
+
}
|
|
322
|
+
return `
|
|
323
|
+
decodeOptional ${decodeType(type.base, jsonElementVar, path, targetVar, suffix, false)}
|
|
324
|
+
`
|
|
325
|
+
.replace(/\n {16}/gu, "\n")
|
|
326
|
+
.trim();
|
|
327
|
+
case parser_1.EnumType:
|
|
328
|
+
case parser_1.StructType:
|
|
329
|
+
return `Decode${type.name} ${jsonElementVar} ${path}`;
|
|
330
|
+
case parser_1.JsonPrimitiveType:
|
|
331
|
+
if (maybeNull) {
|
|
332
|
+
return `
|
|
333
|
+
${jsonElementVar}
|
|
334
|
+
`
|
|
335
|
+
.replace(/\n {16}/gu, "\n")
|
|
336
|
+
.trim();
|
|
337
|
+
}
|
|
338
|
+
return `${targetVar} <- ${jsonElementVar}`;
|
|
339
|
+
case parser_1.DateTimePrimitiveType: {
|
|
340
|
+
return `
|
|
341
|
+
decodeDateTime ${jsonElementVar} ${path}
|
|
342
|
+
`
|
|
343
|
+
.replace(/\n {16}/gu, "\n")
|
|
344
|
+
.trim();
|
|
345
|
+
}
|
|
346
|
+
case parser_1.DatePrimitiveType: {
|
|
347
|
+
return `
|
|
348
|
+
decodeDate ${jsonElementVar} ${path}
|
|
349
|
+
`
|
|
350
|
+
.replace(/\n {16}/gu, "\n")
|
|
351
|
+
.trim();
|
|
352
|
+
}
|
|
353
|
+
case parser_1.ArrayType: {
|
|
354
|
+
return `
|
|
355
|
+
match ${jsonElementVar}.ValueKind with
|
|
356
|
+
| JsonValueKind.Array ->
|
|
357
|
+
let mutable list_ = List.empty
|
|
358
|
+
for i1 in 0 .. (${jsonElementVar}.GetArrayLength() - 1) do
|
|
359
|
+
let item = ${jsonElementVar}.[i1]
|
|
360
|
+
let partialResult =
|
|
361
|
+
${decodeType(type.base, `${jsonElementVar}.[i1]`, `${path.slice(0, -1)}.{i1}"`, targetVar, suffix, false).replace(/\n/gu, "\n ")}
|
|
362
|
+
list_ <- list_ |> List.append [ partialResult ]
|
|
363
|
+
list_
|
|
364
|
+
| _ -> raise (FatalException(${path.slice(0, -1)} must be an array."))
|
|
365
|
+
`
|
|
366
|
+
.replace(/\n {16}/gu, "\n")
|
|
367
|
+
.trim();
|
|
368
|
+
}
|
|
369
|
+
default:
|
|
370
|
+
throw new Error(`BUG: decodeType with ${type.constructor.name}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
exports.decodeType = decodeType;
|
|
374
|
+
function encodeType(type, valueVar, path, suffix = 1, isRef = true) {
|
|
375
|
+
switch (type.constructor) {
|
|
376
|
+
case parser_1.StringPrimitiveType: {
|
|
377
|
+
return `resultWriter_.WriteStringValue(${valueVar})`;
|
|
378
|
+
}
|
|
379
|
+
case parser_1.FloatPrimitiveType:
|
|
380
|
+
case parser_1.UIntPrimitiveType:
|
|
381
|
+
case parser_1.IntPrimitiveType: {
|
|
382
|
+
return `resultWriter_.WriteNumberValue(${valueVar})`;
|
|
383
|
+
}
|
|
384
|
+
case parser_1.MoneyPrimitiveType: {
|
|
385
|
+
return `resultWriter_.WriteNumberValue(int (Math.Round(${valueVar} * 100m)))`;
|
|
386
|
+
}
|
|
387
|
+
case parser_1.BigIntPrimitiveType: {
|
|
388
|
+
return `resultWriter_.WriteStringValue(${valueVar}.ToString())`;
|
|
389
|
+
}
|
|
390
|
+
case parser_1.BoolPrimitiveType: {
|
|
391
|
+
return `resultWriter_.WriteBooleanValue(${valueVar})`;
|
|
392
|
+
}
|
|
393
|
+
case parser_1.BytesPrimitiveType: {
|
|
394
|
+
return `resultWriter_.WriteStringValue(Convert.ToBase64String(${valueVar}))`;
|
|
395
|
+
}
|
|
396
|
+
case parser_1.DateTimePrimitiveType: {
|
|
397
|
+
return `resultWriter_.WriteStringValue(${valueVar}.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFF'Z'"))`;
|
|
398
|
+
}
|
|
399
|
+
case parser_1.DatePrimitiveType: {
|
|
400
|
+
return `resultWriter_.WriteStringValue(${valueVar}.ToString("yyyy-MM-dd"))`;
|
|
401
|
+
}
|
|
402
|
+
// TODO: format those
|
|
403
|
+
case parser_1.CpfPrimitiveType:
|
|
404
|
+
case parser_1.CnpjPrimitiveType:
|
|
405
|
+
case parser_1.EmailPrimitiveType:
|
|
406
|
+
case parser_1.HtmlPrimitiveType:
|
|
407
|
+
case parser_1.UrlPrimitiveType:
|
|
408
|
+
case parser_1.UuidPrimitiveType:
|
|
409
|
+
case parser_1.Base64PrimitiveType:
|
|
410
|
+
case parser_1.HexPrimitiveType:
|
|
411
|
+
case parser_1.XmlPrimitiveType: {
|
|
412
|
+
return `resultWriter_.WriteStringValue(${valueVar})`;
|
|
413
|
+
}
|
|
414
|
+
case parser_1.OptionalType: {
|
|
415
|
+
let realBaseType = type.base;
|
|
416
|
+
while (realBaseType instanceof parser_1.TypeReference) {
|
|
417
|
+
realBaseType = realBaseType.type;
|
|
418
|
+
}
|
|
419
|
+
return `
|
|
420
|
+
if (${valueVar}.IsNone) then
|
|
421
|
+
resultWriter_.WriteNullValue()
|
|
422
|
+
else
|
|
423
|
+
${encodeType(realBaseType, `${valueVar}.Value`, path, suffix, isRef)}
|
|
424
|
+
`
|
|
425
|
+
.replace(/\n {14}/gu, "\n")
|
|
426
|
+
.trim();
|
|
427
|
+
}
|
|
428
|
+
case parser_1.TypeReference:
|
|
429
|
+
return encodeType(type.type, valueVar, path, suffix, isRef);
|
|
430
|
+
case parser_1.EnumType:
|
|
431
|
+
return `Encode${type.name} ${valueVar} resultWriter_ ${path}`;
|
|
432
|
+
case parser_1.StructType:
|
|
433
|
+
return `Encode${type.name} ${valueVar} resultWriter_ ${path}`;
|
|
434
|
+
case parser_1.JsonPrimitiveType:
|
|
435
|
+
return `${valueVar}.WriteTo(resultWriter_)`;
|
|
436
|
+
case parser_1.ArrayType: {
|
|
437
|
+
return `
|
|
438
|
+
resultWriter_.WriteStartArray()
|
|
439
|
+
for i${suffix} in 0..${valueVar}.Length - 1 do
|
|
440
|
+
${encodeType(type.base, `${valueVar}.[i${suffix}]`, `${path}`, suffix + 1).replace(/\n/gu, "\n ")}
|
|
441
|
+
resultWriter_.WriteEndArray()
|
|
442
|
+
`
|
|
443
|
+
.replace(/\n {14}/gu, "\n")
|
|
444
|
+
.trim();
|
|
445
|
+
}
|
|
446
|
+
default:
|
|
447
|
+
throw new Error(`BUG: encodeType with ${type.constructor.name}`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
exports.encodeType = encodeType;
|
|
451
|
+
function generateStruct(struct) {
|
|
452
|
+
return `
|
|
453
|
+
type ${struct.name} = {
|
|
454
|
+
${struct.fields.map(field => `${capitalize(field.name)}: ${generateTypeName(field.type)}`).join(";\n ")}
|
|
455
|
+
} with
|
|
456
|
+
static member Create (${struct.fields.map(field => `${ident(field.name)}: ${generateTypeName(field.type)}`).join(", ")}): ${struct.name} =
|
|
457
|
+
{ ${struct.fields.map(field => `${capitalize(field.name)} = ${ident(field.name)}`).join("; ")} }
|
|
458
|
+
|
|
459
|
+
let Decode${struct.name} (json_: JsonElement) (path_: string): ${struct.name} =
|
|
460
|
+
if (json_.ValueKind <> JsonValueKind.Object) then raise (FatalException($"'{path_}' must be an object."))
|
|
461
|
+
${struct.fields
|
|
462
|
+
.map(field => `
|
|
463
|
+
let ${field.name}Json_ = decodeJsonElementStrict ${JSON.stringify(field.name)} json_ $"{path_}.${field.name}"
|
|
464
|
+
let ${ident(field.name)} =
|
|
465
|
+
${decodeType(field.type, `${field.name}Json_`, `$"{path_}.${field.name}"`, ident(field.name)).replace(/\n/gu, "\n ")}
|
|
466
|
+
`)
|
|
467
|
+
.join("")}
|
|
468
|
+
{ ${struct.fields.map(field => `${capitalize(field.name)} = ${ident(field.name)}`).join("; ")} }
|
|
469
|
+
|
|
470
|
+
let Encode${struct.name} (obj_: ${struct.name}) (resultWriter_: Utf8JsonWriter) (path_: string) =
|
|
471
|
+
resultWriter_.WriteStartObject()
|
|
472
|
+
${struct.fields
|
|
473
|
+
.map(field => `
|
|
474
|
+
resultWriter_.WritePropertyName(${JSON.stringify(field.name)})
|
|
475
|
+
${encodeType(field.type, `obj_.${capitalize(field.name)}`, `$"{path_}.${field.name}"`).replace(/\n/gu, "\n ")}`)
|
|
476
|
+
.join("\n")}
|
|
477
|
+
resultWriter_.WriteEndObject()`;
|
|
478
|
+
}
|
|
479
|
+
exports.generateStruct = generateStruct;
|
|
480
|
+
function generateEnum(type) {
|
|
481
|
+
return `
|
|
482
|
+
type ${type.name} =
|
|
483
|
+
${type.values.map(({ value }) => `| ${capitalize(value)}`).join("\n ")}
|
|
484
|
+
|
|
485
|
+
let Decode${type.name} (json_: JsonElement) (path_: string): ${type.name} =
|
|
486
|
+
if (json_.ValueKind <> JsonValueKind.String) then raise (FatalException($"'{path_}' must be a string."))
|
|
487
|
+
match json_.GetString() with
|
|
488
|
+
${type.values.map(({ value }) => `| "${value}" -> ${type.name}.${capitalize(value)}`).join("\n ")}
|
|
489
|
+
| _ -> raise (FatalException($"'{path_}' must be one of: (${type.values.map(({ value }) => `'${value}'`).join(", ")})."))
|
|
490
|
+
|
|
491
|
+
let Encode${type.name} (obj_: ${type.name}) (resultWriter_: Utf8JsonWriter) (path_: string) =
|
|
492
|
+
match obj_ with
|
|
493
|
+
${type.values.map(({ value }) => `| ${type.name}.${capitalize(value)} -> resultWriter_.WriteStringValue("${value}")`).join("\n ")}
|
|
494
|
+
|
|
495
|
+
`;
|
|
496
|
+
}
|
|
497
|
+
exports.generateEnum = generateEnum;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./fsharp-server"), exports);
|