@game-infra/valibot-to-csharp 0.0.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/README.md +136 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +115 -0
- package/dist/cli.js.map +1 -0
- package/dist/emitter.d.ts +68 -0
- package/dist/emitter.d.ts.map +1 -0
- package/dist/emitter.js +573 -0
- package/dist/emitter.js.map +1 -0
- package/dist/generate.d.ts +101 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +99 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/ir.d.ts +292 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +12 -0
- package/dist/ir.js.map +1 -0
- package/dist/naming.d.ts +53 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +91 -0
- package/dist/naming.js.map +1 -0
- package/dist/parser.d.ts +22 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +321 -0
- package/dist/parser.js.map +1 -0
- package/package.json +38 -0
package/dist/emitter.js
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
import { csStringLiteral, stripSchemaSuffix, toPascalCase } from "./naming.js";
|
|
2
|
+
/**
|
|
3
|
+
* Turn a {@link SchemaModule} into a C# source file body. The caller wraps
|
|
4
|
+
* this with the using-block header (see {@link emitFileHeader}) and writes it
|
|
5
|
+
* to disk.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { emitFileHeader, emitModule, parseFiles } from "@game-infra/valibot-to-csharp";
|
|
10
|
+
*
|
|
11
|
+
* const module = parseFiles(["./schemas/events.ts"]);
|
|
12
|
+
* const emit = emitModule(module, { namespace: "MyGame.Events" });
|
|
13
|
+
* const csFile = emitFileHeader(module.notes) + emit.source;
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function emitModule(module, opts) {
|
|
17
|
+
const ctx = new EmitContext(module, opts);
|
|
18
|
+
// Pre-pass: any named schema referenced as a variant/discriminated-union
|
|
19
|
+
// member becomes a derived record of that variant. We must not also emit it
|
|
20
|
+
// as a standalone top-level record, or the resulting C# won't compile
|
|
21
|
+
// (the derived record can't simultaneously inherit from two different bases
|
|
22
|
+
// and exist as a freestanding type).
|
|
23
|
+
ctx.markVariantMembers();
|
|
24
|
+
// Order: emit variant/discriminated-union bases first so their members are
|
|
25
|
+
// reserved, then the rest. Within each group, stable insertion order.
|
|
26
|
+
for (const named of module.schemas.values()) {
|
|
27
|
+
if (isVariantLike(named.schema))
|
|
28
|
+
ctx.emitNamed(named);
|
|
29
|
+
}
|
|
30
|
+
for (const named of module.schemas.values()) {
|
|
31
|
+
if (!isVariantLike(named.schema))
|
|
32
|
+
ctx.emitNamed(named);
|
|
33
|
+
}
|
|
34
|
+
if (ctx.usesStringOrStringList) {
|
|
35
|
+
ctx.emitStringOrStringList();
|
|
36
|
+
}
|
|
37
|
+
const body = ctx.typeDecls.join("\n\n");
|
|
38
|
+
const wrapped = `\nnamespace ${opts.namespace};\n\n${body}\n`;
|
|
39
|
+
return { source: wrapped, usesStringOrStringList: ctx.usesStringOrStringList };
|
|
40
|
+
}
|
|
41
|
+
function isVariantLike(node) {
|
|
42
|
+
if (node.kind === "variant")
|
|
43
|
+
return true;
|
|
44
|
+
if (node.kind === "union") {
|
|
45
|
+
// Heuristic: unions of all-object-literals with a shared discriminator.
|
|
46
|
+
// Re-classifying here would require the context; keep it simple and let
|
|
47
|
+
// the emitter decide. This ordering only affects when emitNamed runs for
|
|
48
|
+
// the base, not correctness.
|
|
49
|
+
return (node.members.length > 0 && node.members.every((m) => m.kind === "object" || m.kind === "ref"));
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Render the file-level header: auto-generated banner + using-block. Split out
|
|
55
|
+
* so callers that want to embed the emitter output in larger files can skip it.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { emitFileHeader } from "@game-infra/valibot-to-csharp";
|
|
60
|
+
*
|
|
61
|
+
* const header = emitFileHeader([]);
|
|
62
|
+
* // "// <auto-generated>..." plus the System.Text.Json using-block
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function emitFileHeader(notes) {
|
|
66
|
+
const lines = [
|
|
67
|
+
"// <auto-generated>",
|
|
68
|
+
"// This file was generated by @game-infra/valibot-to-csharp.",
|
|
69
|
+
"// Do not edit by hand; regenerate from the valibot source instead.",
|
|
70
|
+
"// </auto-generated>",
|
|
71
|
+
];
|
|
72
|
+
for (const note of notes) {
|
|
73
|
+
lines.push(`// ${note}`);
|
|
74
|
+
}
|
|
75
|
+
lines.push("");
|
|
76
|
+
lines.push("using System.Collections.Generic;");
|
|
77
|
+
lines.push("using System.Text.Json;");
|
|
78
|
+
lines.push("using System.Text.Json.Serialization;");
|
|
79
|
+
lines.push("");
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
class EmitContext {
|
|
83
|
+
module;
|
|
84
|
+
opts;
|
|
85
|
+
typeDecls = [];
|
|
86
|
+
usesStringOrStringList = false;
|
|
87
|
+
/** Names already emitted, to avoid duplicates on cross-references. */
|
|
88
|
+
emittedTypeNames = new Set();
|
|
89
|
+
/** Track named schemas already fully emitted, keyed by source const name. */
|
|
90
|
+
emittedNamed = new Set();
|
|
91
|
+
/**
|
|
92
|
+
* Named schemas that will be emitted as variant members. They must not
|
|
93
|
+
* also be emitted as top-level standalone records.
|
|
94
|
+
*/
|
|
95
|
+
variantMemberNames = new Set();
|
|
96
|
+
constructor(module, opts) {
|
|
97
|
+
this.module = module;
|
|
98
|
+
this.opts = opts;
|
|
99
|
+
}
|
|
100
|
+
/** Pre-pass: mark every named schema referenced as a variant member. */
|
|
101
|
+
markVariantMembers() {
|
|
102
|
+
for (const named of this.module.schemas.values()) {
|
|
103
|
+
const collected = this.collectVariantMembers(named.schema);
|
|
104
|
+
for (const n of collected)
|
|
105
|
+
this.variantMemberNames.add(n);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
collectVariantMembers(node) {
|
|
109
|
+
if (node.kind === "variant") {
|
|
110
|
+
return this.refsInMembers(node.members);
|
|
111
|
+
}
|
|
112
|
+
if (node.kind === "union") {
|
|
113
|
+
const shape = this.classifyUnion(node.members);
|
|
114
|
+
if (shape.kind === "discriminated") {
|
|
115
|
+
return this.refsInMembers(node.members);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
refsInMembers(members) {
|
|
121
|
+
const out = [];
|
|
122
|
+
for (const m of members) {
|
|
123
|
+
if (m.kind === "ref")
|
|
124
|
+
out.push(m.name);
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/** Top-level emit for a named schema. */
|
|
129
|
+
emitNamed(named) {
|
|
130
|
+
if (this.emittedNamed.has(named.name))
|
|
131
|
+
return;
|
|
132
|
+
this.emittedNamed.add(named.name);
|
|
133
|
+
// If this named schema is going to be emitted as a derived record of a
|
|
134
|
+
// discriminated union, skip the standalone emit. It'll be produced by
|
|
135
|
+
// the variant's own emitter pass.
|
|
136
|
+
if (this.variantMemberNames.has(named.name) && named.schema.kind === "object") {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const typeName = this.csTypeNameForNamed(named.name);
|
|
140
|
+
const inner = named.schema;
|
|
141
|
+
switch (inner.kind) {
|
|
142
|
+
case "object":
|
|
143
|
+
this.emitRecord(typeName, inner);
|
|
144
|
+
return;
|
|
145
|
+
case "picklist":
|
|
146
|
+
this.emitEnum(typeName, inner.values);
|
|
147
|
+
return;
|
|
148
|
+
case "variant":
|
|
149
|
+
this.emitVariant(typeName, inner);
|
|
150
|
+
return;
|
|
151
|
+
case "union": {
|
|
152
|
+
const shape = this.classifyUnion(inner.members);
|
|
153
|
+
if (shape.kind === "enum") {
|
|
154
|
+
this.emitEnum(typeName, shape.values);
|
|
155
|
+
}
|
|
156
|
+
else if (shape.kind === "discriminated") {
|
|
157
|
+
// Build a synthetic VariantNode so we can reuse the variant emitter.
|
|
158
|
+
this.emitVariant(typeName, {
|
|
159
|
+
kind: "variant",
|
|
160
|
+
discriminator: shape.discriminator,
|
|
161
|
+
// pass through the original union members; emitVariant re-resolves.
|
|
162
|
+
members: inner.members,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else if (shape.kind === "stringOrList") {
|
|
166
|
+
// Named string-or-list unions are consumed inline via the
|
|
167
|
+
// StringOrStringList helper. No standalone type needed.
|
|
168
|
+
this.usesStringOrStringList = true;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
this.typeDecls.push([
|
|
172
|
+
`// TODO: ${named.name} is a heterogeneous union not yet supported.`,
|
|
173
|
+
`// Falling back to JsonElement. Extend the emitter if richer typing is needed.`,
|
|
174
|
+
`public sealed record ${typeName}(JsonElement Value);`,
|
|
175
|
+
].join("\n"));
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
case "primitive":
|
|
180
|
+
case "literal":
|
|
181
|
+
case "array":
|
|
182
|
+
case "record":
|
|
183
|
+
case "unknown":
|
|
184
|
+
case "ref":
|
|
185
|
+
case "nullable":
|
|
186
|
+
case "optional":
|
|
187
|
+
// These don't produce a standalone type declaration. Callers that
|
|
188
|
+
// reference this name inline its C# expression via `csExpression`.
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
emitRecord(name, obj) {
|
|
193
|
+
if (this.emittedTypeNames.has(name))
|
|
194
|
+
return;
|
|
195
|
+
this.emittedTypeNames.add(name);
|
|
196
|
+
if (obj.fields.length === 0) {
|
|
197
|
+
this.typeDecls.push(`public sealed record ${name}();`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const lines = [];
|
|
201
|
+
lines.push(`public sealed record ${name}(`);
|
|
202
|
+
const fieldLines = [];
|
|
203
|
+
for (const f of obj.fields) {
|
|
204
|
+
fieldLines.push(this.emitField(f, name));
|
|
205
|
+
}
|
|
206
|
+
lines.push(fieldLines.map((l) => ` ${l}`).join(",\n"));
|
|
207
|
+
lines.push(");");
|
|
208
|
+
this.typeDecls.push(lines.join("\n"));
|
|
209
|
+
}
|
|
210
|
+
emitField(f, parentTypeName) {
|
|
211
|
+
const optionalOrNullable = f.optional || f.nullable;
|
|
212
|
+
const propName = toPascalCase(f.name);
|
|
213
|
+
// Nested anonymous types get the enclosing type prepended to their hint
|
|
214
|
+
// (e.g. AddScore.params → AddScoreParams) so sibling objects don't
|
|
215
|
+
// collide on identically-named inline fields.
|
|
216
|
+
const { csType, inlineDecls } = this.csExpression(f.schema, {
|
|
217
|
+
parentHint: `${parentTypeName}${propName}`,
|
|
218
|
+
});
|
|
219
|
+
for (const d of inlineDecls)
|
|
220
|
+
this.typeDecls.push(d);
|
|
221
|
+
const suffix = optionalOrNullable ? "?" : "";
|
|
222
|
+
return `[property: JsonPropertyName(${csStringLiteral(f.name)})] ${csType}${suffix} ${propName}`;
|
|
223
|
+
}
|
|
224
|
+
emitEnum(name, values) {
|
|
225
|
+
if (this.emittedTypeNames.has(name))
|
|
226
|
+
return;
|
|
227
|
+
this.emittedTypeNames.add(name);
|
|
228
|
+
const lines = [];
|
|
229
|
+
lines.push("[JsonConverter(typeof(JsonStringEnumConverter))]");
|
|
230
|
+
lines.push(`public enum ${name}`);
|
|
231
|
+
lines.push("{");
|
|
232
|
+
const memberLines = [];
|
|
233
|
+
for (const v of values) {
|
|
234
|
+
memberLines.push(` [JsonStringEnumMemberName(${csStringLiteral(v)})]\n ${toPascalCase(v)}`);
|
|
235
|
+
}
|
|
236
|
+
lines.push(memberLines.join(",\n"));
|
|
237
|
+
lines.push("}");
|
|
238
|
+
this.typeDecls.push(lines.join("\n"));
|
|
239
|
+
}
|
|
240
|
+
emitVariant(name, variant) {
|
|
241
|
+
if (this.emittedTypeNames.has(name))
|
|
242
|
+
return;
|
|
243
|
+
this.emittedTypeNames.add(name);
|
|
244
|
+
const members = this.resolveVariantMembers(variant.members);
|
|
245
|
+
if (members.length === 0) {
|
|
246
|
+
// No resolvable members: emit a placeholder so cross-refs resolve.
|
|
247
|
+
this.typeDecls.push([
|
|
248
|
+
`// TODO: variant ${name} had no resolvable object members.`,
|
|
249
|
+
`public abstract record ${name}(string ${toPascalCase(variant.discriminator)});`,
|
|
250
|
+
].join("\n"));
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
// Base abstract record with polymorphism attributes.
|
|
254
|
+
const baseLines = [];
|
|
255
|
+
baseLines.push(`[JsonPolymorphic(TypeDiscriminatorPropertyName = ${csStringLiteral(variant.discriminator)})]`);
|
|
256
|
+
for (const m of members) {
|
|
257
|
+
baseLines.push(`[JsonDerivedType(typeof(${m.typeName}), ${csStringLiteral(m.tag)})]`);
|
|
258
|
+
}
|
|
259
|
+
baseLines.push(`public abstract record ${name}([property: JsonPropertyName(${csStringLiteral(variant.discriminator)})] string ${toPascalCase(variant.discriminator)});`);
|
|
260
|
+
this.typeDecls.push(baseLines.join("\n"));
|
|
261
|
+
// Derived records, one per member.
|
|
262
|
+
for (const m of members) {
|
|
263
|
+
if (this.emittedTypeNames.has(m.typeName))
|
|
264
|
+
continue;
|
|
265
|
+
this.emittedTypeNames.add(m.typeName);
|
|
266
|
+
// Fields minus the discriminator.
|
|
267
|
+
const fields = m.schema.fields.filter((f) => f.name !== variant.discriminator);
|
|
268
|
+
const lines = [];
|
|
269
|
+
if (fields.length === 0) {
|
|
270
|
+
lines.push(`public sealed record ${m.typeName}() : ${name}(${csStringLiteral(m.tag)});`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
lines.push(`public sealed record ${m.typeName}(`);
|
|
274
|
+
const fieldLines = fields.map((f) => this.emitField(f, m.typeName));
|
|
275
|
+
lines.push(fieldLines.map((l) => ` ${l}`).join(",\n"));
|
|
276
|
+
lines.push(`) : ${name}(${csStringLiteral(m.tag)});`);
|
|
277
|
+
}
|
|
278
|
+
this.typeDecls.push(lines.join("\n"));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Render a SchemaNode as an inline C# type reference, emitting any
|
|
283
|
+
* nested-type declarations required to support it. Returns both the textual
|
|
284
|
+
* C# type (e.g. "IReadOnlyList<string>") and any extra decls the caller
|
|
285
|
+
* should push into the module.
|
|
286
|
+
*/
|
|
287
|
+
csExpression(node, ctx) {
|
|
288
|
+
const decls = [];
|
|
289
|
+
const csType = this.toCsType(node, ctx, decls);
|
|
290
|
+
return { csType, inlineDecls: decls };
|
|
291
|
+
}
|
|
292
|
+
toCsType(node, ctx, decls) {
|
|
293
|
+
switch (node.kind) {
|
|
294
|
+
case "primitive":
|
|
295
|
+
if (node.type === "string")
|
|
296
|
+
return "string";
|
|
297
|
+
if (node.type === "number")
|
|
298
|
+
return "double";
|
|
299
|
+
return "bool";
|
|
300
|
+
case "unknown":
|
|
301
|
+
return "JsonElement";
|
|
302
|
+
case "literal":
|
|
303
|
+
return "string";
|
|
304
|
+
case "ref": {
|
|
305
|
+
// Try to resolve the referenced named schema so we know what C#
|
|
306
|
+
// shape it ultimately maps to (important for enums / variants
|
|
307
|
+
// whose C# name isn't simply the PascalCase of the const).
|
|
308
|
+
const resolved = this.module.schemas.get(node.name);
|
|
309
|
+
if (resolved) {
|
|
310
|
+
// Named unions that collapse to string|string[] should be
|
|
311
|
+
// substituted with the shared helper type.
|
|
312
|
+
if (resolved.schema.kind === "union") {
|
|
313
|
+
const shape = this.classifyUnion(resolved.schema.members);
|
|
314
|
+
if (shape.kind === "stringOrList") {
|
|
315
|
+
this.usesStringOrStringList = true;
|
|
316
|
+
return "StringOrStringList";
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return this.csTypeNameForNamed(node.name);
|
|
320
|
+
}
|
|
321
|
+
// Unknown reference. Best guess: treat as a C# type of the same
|
|
322
|
+
// stripped name (the author likely knows what they're doing).
|
|
323
|
+
return stripSchemaSuffix(node.name);
|
|
324
|
+
}
|
|
325
|
+
case "array": {
|
|
326
|
+
const inner = this.toCsType(node.inner, ctx, decls);
|
|
327
|
+
return `IReadOnlyList<${inner}>`;
|
|
328
|
+
}
|
|
329
|
+
case "record": {
|
|
330
|
+
const inner = this.toCsType(node.value, ctx, decls);
|
|
331
|
+
return `IReadOnlyDictionary<string, ${inner}>`;
|
|
332
|
+
}
|
|
333
|
+
case "optional":
|
|
334
|
+
case "nullable":
|
|
335
|
+
// Nullability is tracked on the field, not the type itself. If we
|
|
336
|
+
// ever see this unwrapped (shouldn't happen because the parser peels
|
|
337
|
+
// it into field flags), emit the inner type.
|
|
338
|
+
return this.toCsType(node.inner, ctx, decls);
|
|
339
|
+
case "object": {
|
|
340
|
+
// Anonymous nested object: synthesise a record named from the hint.
|
|
341
|
+
const typeName = this.freshTypeName(ctx.parentHint);
|
|
342
|
+
this.emitRecord(typeName, node);
|
|
343
|
+
return typeName;
|
|
344
|
+
}
|
|
345
|
+
case "picklist": {
|
|
346
|
+
// Anonymous enum: name it from the parent field.
|
|
347
|
+
const typeName = this.freshTypeName(ctx.parentHint);
|
|
348
|
+
this.emitEnum(typeName, node.values);
|
|
349
|
+
return typeName;
|
|
350
|
+
}
|
|
351
|
+
case "union": {
|
|
352
|
+
const shape = this.classifyUnion(node.members);
|
|
353
|
+
if (shape.kind === "enum") {
|
|
354
|
+
const typeName = this.freshTypeName(ctx.parentHint);
|
|
355
|
+
this.emitEnum(typeName, shape.values);
|
|
356
|
+
return typeName;
|
|
357
|
+
}
|
|
358
|
+
if (shape.kind === "stringOrList") {
|
|
359
|
+
this.usesStringOrStringList = true;
|
|
360
|
+
return "StringOrStringList";
|
|
361
|
+
}
|
|
362
|
+
if (shape.kind === "discriminated") {
|
|
363
|
+
const typeName = this.freshTypeName(ctx.parentHint);
|
|
364
|
+
this.emitVariant(typeName, {
|
|
365
|
+
kind: "variant",
|
|
366
|
+
discriminator: shape.discriminator,
|
|
367
|
+
members: node.members,
|
|
368
|
+
});
|
|
369
|
+
return typeName;
|
|
370
|
+
}
|
|
371
|
+
// Generic union: fall back.
|
|
372
|
+
return "JsonElement";
|
|
373
|
+
}
|
|
374
|
+
case "variant": {
|
|
375
|
+
const typeName = this.freshTypeName(ctx.parentHint);
|
|
376
|
+
this.emitVariant(typeName, node);
|
|
377
|
+
return typeName;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Figure out the C# type name for a named schema. Handles overrides via
|
|
383
|
+
* the unionRenames option.
|
|
384
|
+
*/
|
|
385
|
+
csTypeNameForNamed(sourceName) {
|
|
386
|
+
const override = this.opts.unionRenames?.get(sourceName);
|
|
387
|
+
if (override)
|
|
388
|
+
return override;
|
|
389
|
+
return stripSchemaSuffix(sourceName);
|
|
390
|
+
}
|
|
391
|
+
classifyUnion(members) {
|
|
392
|
+
if (members.length === 0)
|
|
393
|
+
return { kind: "generic" };
|
|
394
|
+
// All literals → enum.
|
|
395
|
+
if (members.every((m) => m.kind === "literal")) {
|
|
396
|
+
return {
|
|
397
|
+
kind: "enum",
|
|
398
|
+
values: members.map((m) => m.value),
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
// string | string[] → StringOrStringList.
|
|
402
|
+
if (members.length === 2) {
|
|
403
|
+
const hasString = members.some((m) => m.kind === "primitive" && m.type === "string");
|
|
404
|
+
const hasStringArray = members.some((m) => m.kind === "array" && m.inner.kind === "primitive" && m.inner.type === "string");
|
|
405
|
+
if (hasString && hasStringArray)
|
|
406
|
+
return { kind: "stringOrList" };
|
|
407
|
+
}
|
|
408
|
+
// All members are object({ type: literal(...) }) or refs to such → discriminated.
|
|
409
|
+
const resolved = [];
|
|
410
|
+
let discriminator = null;
|
|
411
|
+
let ok = true;
|
|
412
|
+
for (const m of members) {
|
|
413
|
+
const r = this.resolveObjectMember(m);
|
|
414
|
+
if (!r) {
|
|
415
|
+
ok = false;
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
if (discriminator === null)
|
|
419
|
+
discriminator = r.discriminator;
|
|
420
|
+
else if (r.discriminator !== discriminator) {
|
|
421
|
+
ok = false;
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
resolved.push({
|
|
425
|
+
tag: r.tag,
|
|
426
|
+
typeName: r.typeName,
|
|
427
|
+
schema: r.schema,
|
|
428
|
+
sourceName: r.sourceName,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
if (ok && discriminator && resolved.length > 0) {
|
|
432
|
+
return { kind: "discriminated", discriminator, members: resolved };
|
|
433
|
+
}
|
|
434
|
+
return { kind: "generic" };
|
|
435
|
+
}
|
|
436
|
+
/** Resolve the members argument of a `variant(...)` (or synthesised from a union). */
|
|
437
|
+
resolveVariantMembers(members) {
|
|
438
|
+
const resolved = [];
|
|
439
|
+
for (const m of members) {
|
|
440
|
+
const r = this.resolveObjectMember(m);
|
|
441
|
+
if (r) {
|
|
442
|
+
resolved.push({
|
|
443
|
+
tag: r.tag,
|
|
444
|
+
typeName: r.typeName,
|
|
445
|
+
schema: r.schema,
|
|
446
|
+
sourceName: r.sourceName,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return resolved;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Normalise a union/variant member into { discriminator tag, C# type name,
|
|
454
|
+
* object schema }. Follows refs to named object schemas. Returns null if
|
|
455
|
+
* the member doesn't look like `object({ type: literal('X'), ... })`.
|
|
456
|
+
*/
|
|
457
|
+
resolveObjectMember(node) {
|
|
458
|
+
let obj = null;
|
|
459
|
+
let sourceName;
|
|
460
|
+
if (node.kind === "object") {
|
|
461
|
+
obj = node;
|
|
462
|
+
}
|
|
463
|
+
else if (node.kind === "ref") {
|
|
464
|
+
const named = this.module.schemas.get(node.name);
|
|
465
|
+
if (named && named.schema.kind === "object") {
|
|
466
|
+
obj = named.schema;
|
|
467
|
+
sourceName = node.name;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (!obj)
|
|
471
|
+
return null;
|
|
472
|
+
// Find a field whose schema is a literal. Any field will do, but we
|
|
473
|
+
// prefer `type`.
|
|
474
|
+
let discField = null;
|
|
475
|
+
for (const f of obj.fields) {
|
|
476
|
+
if (f.schema.kind === "literal" && f.name === "type") {
|
|
477
|
+
discField = f;
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
if (!discField) {
|
|
482
|
+
for (const f of obj.fields) {
|
|
483
|
+
if (f.schema.kind === "literal") {
|
|
484
|
+
discField = f;
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if (!discField || discField.schema.kind !== "literal")
|
|
490
|
+
return null;
|
|
491
|
+
const tag = discField.schema.value;
|
|
492
|
+
const typeName = sourceName
|
|
493
|
+
? stripSchemaSuffix(sourceName)
|
|
494
|
+
: this.freshTypeName(toPascalCase(tag));
|
|
495
|
+
return {
|
|
496
|
+
discriminator: discField.name,
|
|
497
|
+
tag,
|
|
498
|
+
typeName,
|
|
499
|
+
schema: obj,
|
|
500
|
+
sourceName,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Generate a type name unique across the module. Used for anonymous nested
|
|
505
|
+
* types (fields whose inline schema is an object, picklist, or union).
|
|
506
|
+
*/
|
|
507
|
+
freshTypeName(hint) {
|
|
508
|
+
const base = toPascalCase(hint) || "Anon";
|
|
509
|
+
if (!this.emittedTypeNames.has(base) && !this.isReservedName(base)) {
|
|
510
|
+
return base;
|
|
511
|
+
}
|
|
512
|
+
let i = 2;
|
|
513
|
+
while (this.emittedTypeNames.has(`${base}${i}`) || this.isReservedName(`${base}${i}`)) {
|
|
514
|
+
i++;
|
|
515
|
+
}
|
|
516
|
+
return `${base}${i}`;
|
|
517
|
+
}
|
|
518
|
+
isReservedName(name) {
|
|
519
|
+
// Avoid colliding with a to-be-emitted named schema.
|
|
520
|
+
for (const s of this.module.schemas.values()) {
|
|
521
|
+
if (this.csTypeNameForNamed(s.name) === name)
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
emitStringOrStringList() {
|
|
527
|
+
if (this.emittedTypeNames.has("StringOrStringList"))
|
|
528
|
+
return;
|
|
529
|
+
this.emittedTypeNames.add("StringOrStringList");
|
|
530
|
+
const body = `[JsonConverter(typeof(StringOrStringListConverter))]
|
|
531
|
+
public sealed record StringOrStringList(IReadOnlyList<string> Values)
|
|
532
|
+
{
|
|
533
|
+
public static implicit operator StringOrStringList(string value) => new(new[] { value });
|
|
534
|
+
public static implicit operator StringOrStringList(string[] values) => new(values);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
public sealed class StringOrStringListConverter : JsonConverter<StringOrStringList>
|
|
538
|
+
{
|
|
539
|
+
public override StringOrStringList Read(ref Utf8JsonReader reader, System.Type typeToConvert, JsonSerializerOptions options)
|
|
540
|
+
{
|
|
541
|
+
if (reader.TokenType == JsonTokenType.String)
|
|
542
|
+
{
|
|
543
|
+
var single = reader.GetString() ?? string.Empty;
|
|
544
|
+
return new StringOrStringList(new[] { single });
|
|
545
|
+
}
|
|
546
|
+
if (reader.TokenType == JsonTokenType.StartArray)
|
|
547
|
+
{
|
|
548
|
+
var list = new List<string>();
|
|
549
|
+
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
|
|
550
|
+
{
|
|
551
|
+
list.Add(reader.GetString() ?? string.Empty);
|
|
552
|
+
}
|
|
553
|
+
return new StringOrStringList(list);
|
|
554
|
+
}
|
|
555
|
+
throw new JsonException("Expected string or array of strings for StringOrStringList.");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
public override void Write(Utf8JsonWriter writer, StringOrStringList value, JsonSerializerOptions options)
|
|
559
|
+
{
|
|
560
|
+
if (value.Values.Count == 1)
|
|
561
|
+
{
|
|
562
|
+
writer.WriteStringValue(value.Values[0]);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
writer.WriteStartArray();
|
|
566
|
+
foreach (var v in value.Values) writer.WriteStringValue(v);
|
|
567
|
+
writer.WriteEndArray();
|
|
568
|
+
}
|
|
569
|
+
}`;
|
|
570
|
+
this.typeDecls.push(body);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
//# sourceMappingURL=emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
|